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

时间:2017-08-19 17:20:20

标签: python docker

最近我正在写一个静态页面生成器。 我想使用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的配置文件中,有一些中文字符。我在我自己的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? 或者某个地方要求帮助?

提前谢谢。

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

2 个答案:

答案 0 :(得分:1)

好的,我找到了原因。

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

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

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

此外,在docker服务器中,我们不能使用中文字符作为文件名,因为在docker服务器中,默认字符编码不支持中文字符。因此,码头工具中的中文文件名将变得像2017-08-19 - ???????????? yml&#39;。如果确保所有文件名都是ascii字符,并在python3中打开文件时指定编码参数。一切都好。

更多详情请见here

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

contentDocument

它适用于nginx:最新图像。它可能依赖于泊坞窗图像,因为只能指定ENV LANG C.UTF-8无法修复我的泊坞窗图像。

答案 1 :(得分:1)

您可以在docker文件中指定ENV LANG C.UTF-8以解决此问题(在open命令位于您不想更改的第三方库中时非常重要)