重現步驟:集文件系統編碼蟒3上的英特爾愛迪生
- 創建文件
test.txt
與內容This is 中文
(即UTF-8編碼的非ASCII文本)。 - 在英特爾Edison上自定義編譯python 3.5.2。
啓動自定義編譯python3解釋,併發出以下一段代碼:
with open('test.txt', 'r') as fh: fh.readlines()
實際行爲:
一個UnicodeDecodeError
拋出異常。該文件默認打開爲「ASCII」而不是「UTF-8」:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 8: ordinal not in range(128)
在「常規」 Linux系統這個問題很容易通過設置適當的語言環境來解決,例如見this post或that post。但是,在Intel Edison上,由於默認的Yocto Linux發行版缺少語言環境,因此無法設置LC_CTYPE
(請參閱,例如this page)。
我還試圖用其他幾個黑客像
import sys; sys.getfilesystemencoding = lambda: 'UTF-8'
import locale; locale.getpreferredencoding = lambda: 'utf-8'
我試着開始Python解釋器之前設置PYTHONIOENCODING=utf8
環境變量。
但是,這些都不起作用。唯一的解決方法是將編碼明確指定爲open
命令的命令行參數。這適用於上面的代碼片段,但它不會爲我使用的所有軟件包設置系統範圍的默認值(這會隱式地將文件作爲ASCII打開,可能會或可能不會爲我們提供覆蓋默認行爲的方法)。
什麼是設置python解釋器默認文件系統編碼的正確方法? (當然了,無需安裝不需要的系統範圍內的區域設置)
爲什麼不只是使用'open('te st.txt','r',encoding ='utf8')'?顯式比隱式更好。不要使用黑客。 –
'sys.getfilesystemencoding()'不用於確定新打開的文件的編碼。替換'locale.getpreferredencoding'將不起作用,因爲打開文件的* C代碼不會調用Python版本,它可以直接訪問原始的C函數。 –
'PYTHONIOENCODING'適用於'stdin','stdout'和'stderr',而不是'open()'。 –