Docker,python3 yaml.safe_load()读取中文文件无法正常工作

最近我正在写静态页面生成器。 我想用docker来部署我的项目。 我使用python3。

def load_posts_config(config): metadata = {} for c in os.listdir(config['articles']['config']): cpath = os.path.join(config['articles']['config'], c) cfh = open(cpath, 'r') meta = yaml.safe_load(cfh) cfh.close() metadata[meta['post_id']] = meta return metadata 

cfh的configuration文件中,有一些中文字符。 我在自己的Ubuntu 16.04LTS,python3.5.2中运行我的脚本。 但是,当我在docker(python版本是3.5.3)中运行它时,它输出错误:

 root@a0affea32648:/build/blog# python3 bumblebee.py Traceback (most recent call last): File "bumblebee.py", line 80, in <module> article_infos = load_posts_config(config) File "bumblebee.py", line 56, in load_posts_config meta = yaml.safe_load(cfh) File "/usr/local/lib/python3.5/dist-packages/yaml/__init__.py", line 70, in load loader = Loader(stream) File "/usr/local/lib/python3.5/dist-packages/yaml/loader.py", line 34, in __init__ Reader.__init__(self, stream) File "/usr/local/lib/python3.5/dist-packages/yaml/reader.py", line 85, in __init__ self.determine_encoding() File "/usr/local/lib/python3.5/dist-packages/yaml/reader.py", line 124, in determine_encoding self.update_raw() File "/usr/local/lib/python3.5/dist-packages/yaml/reader.py", line 178, in update_raw data = self.stream.read(size) File "/usr/lib/python3.5/encodings/ascii.py", line 26, in decode return codecs.ascii_decode(input, self.errors)[0] UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 16: ordinal not in range(128) 

这很奇怪。 我认为python3可以处理所有的unicode,我可以在我的本地计算机上运行它。 唯一的区别是python版本和环境,Ubuntu16.04lts工程中的python3.5.2和docker中的python3.5.3没有。

有谁知道这个问题? 或者如何在我的Ubuntu 16.04 LTS中将python3.5.2更新到python3.5.3? 或者在某处寻求帮助?

Thx提前。

(PS:我试过yaml.load()但失败了)

你可以在你的ENV LANG C.UTF-8文件中指定ENV LANG C.UTF-8来解决这个问题(在open命令在你不想改变的第三方库中的情况下是很重要的)

好的,我find了原因。

两种环境之间的差异是默认的字符编码,你可以使用这个脚本来检查默认编码:

 >>> import locale >>> locale.getpreferredencoding() 

在我的Ubuntu16.4lts中是“UTF-8”,而在docker服务器中是“ANSI_X3.4-1968”。 所以当我们打开一个文件的时候我们需要指定一个编码参数。 然后它可以工作。

另外,在docker服务器中,我们不能使用中文字符作为文件名,因为在docker服务器中默认的字符编码不支持汉字。 所以Docker中的中文文件名就会变成'2017-08-19 – ????????????.YML'。 如果你确定你所有的文件名都是ascii字符,并且在python3中打开一个文件时指定一个编码参数。 然后一切都好。

更多细节在这里 。

解决scheme:在Dockerfile中,添加以下代码:

 ENV LANG="en_US.UTF-8" RUN apt-get update && apt-get install -y locales RUN echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && \ cp /etc/locale.alias /usr/share/locale/ && \ locale-gen en_US.UTF-8 && \ /usr/sbin/update-locale LANG=en_US.UTF-8 ENV LC_ALL en_US.UTF-8 

它工作在nginx:最新的图像。 这可能取决于docker图像造成只有指定ENV LANG C.UTF-8无法修复我的docker图像。