我司现在使用Airflow,搭建在Python3环境上,奇怪的是,在代码里不能出现中文,print\logging的时候,如果有中文,就报错:
UnicodeEncodeError: 'ascii' codec can't encode character u'***' in position ***: ordinal not in range(128)
我的疑问有二:
经多方查询,发现在docker镜像中,由于locale的设置问题,导致Python3并没有使用utf-8作为sysout编码。
关于什么是locale
,可以查看ubuntu的官方文档https://wiki.ubuntu.org.cn/Locale,简而言之,它定义了系统里文字使用何种方式编码。默认的ubuntu:18.04镜像的locale是POSIX,这种设置会默认使用ascii编码,从而导致上面的错误。
在环境中输入:
$ python -c "import sys; print(sys.stdout.encoding)"
UTF-8
如果你的返回值不是UTF-8
,那么你很有可能会遇到unicode输入问题
注意,以下代码返回UTF-8并不能说明没有问题
python -c "import sys; print(sys.getdefaultencoding())"
设置docker中的环境变量,使Python可以使用正确的编码方式
在Dockerfile中添加:
ENV PYTHONIOENCODING=UTF-8
据说此方法可以解决问题,但是我没有成功,locale问题依然存在,有兴趣的同学可以试一下。
在Dockerfile中添加:
RUN apt-get update
RUN apt-get install -y locales
RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \
locale-gen
ENV LC_ALL en_US.UTF-8
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
设置完成
这可能是最简单的办法了,Python3.7中,PEP-538说明,默认将Python的locale从C
、POSIX
改为默认为UTF-8
.
详见 https://docs.python.org/3.7/whatsnew/3.7.html#whatsnew37-pep538
所以如果你没有强依赖的话,可以考虑换3.7的镜像。