2017-08-19 210 views
1

最近我寫了一個靜態頁面生成器。 我想用docker來部署我的項目。我使用python3。Docker,python3 yaml.safe_load()讀取中文文件無法正常工作

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中運行我的腳本。然而,當我在泊塢窗跑了(其中Python版本3.5.3是),它輸出錯誤:

[email protected]:/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()但失敗了)

+0

試試這個,看看它是否指定ENV LANG C.UTF-8'進口IO; cfh = io.open(cpath,'r',encoding =「utf-8」);' –

回答

1

OK,我已經找到了原因。

兩個環境之間的diffence是默認的字符編碼,你可以使用這個腳本來檢查默認編碼:

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

在我Ubuntu16.4lts是「UTF-8」,而在碼頭服務器它是'ANSI_X3.4-1968'。所以我們需要在打開文件時指定一個編碼參數。然後它可以工作。

另外,在碼頭服務器中,我們不能使用中文字符作爲文件名,因爲在碼頭服務器中缺省字符編碼不支持漢字。所以docker中的中文文件名就會變成'2017-08-19 - ????????????。yml'。如果你確保你所有的文件名都是ascii字符並且當我們在python3中打開一個文件時指定一個編碼參數。然後一切都很好。

更多細節請見here

解決方案: 在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的:最新圖像。這可能取決於碼頭圖像導致只有指定ENV LANG C.UTF-8無法修復我的碼頭圖像。

1

您可以在泊塢窗文件來解決此問題(在案件的重要的地方打開命令是在第三方庫,你不想改變)

+0

thx。我已經嘗試過但失敗了。也許這取決於碼頭的圖像。我已更新我的帖子,添加我的解決方案。 – longj