[英]Python3 utf-8 decode issue
以下代碼在我的Windows機器上使用Python3運行正常並打印字符'é':
data = b"\xc3\xa9"
print(data.decode('utf-8'))
但是,在基於Ubuntu的docker容器上運行相同會導致:
UnicodeEncodeError: 'ascii' codec can't encode character '\xe9' in position 0: ordinal not in range(128)
有什么必須安裝才能啟用utf-8解碼嗎?
問題在於print()
表達式,而不是decode()
方法。 如果你仔細一看,出現的異常是Unicode 恩 codeError,而不是一個- 德 codeError。
每當你使用print()
函數時,Python都會將其參數轉換為str
,然后將結果編碼為bytes
,這些bytes
將被發送到終端(或運行的任何Python)。 用於編碼的編解碼器(例如UTF-8或ASCII)取決於環境。 在一個理想的情況下,
在您的情況下,您提到的Linux docker不符合第二個條件:使用的編碼是ASCII,它只支持舊英文打字機上的字符。 這些是解決此問題的幾個選項:
LC_ALL
設置為包含“UTF-8”的東西曾經為我工作過一次。 您必須將它們放在終端運行的shell的啟動腳本中,例如。 .bashrc 。 重新編碼STDOUT,如下所示:
sys.stdout = open(sys.stdout.buffer.fileno(), 'w', encoding='utf8')
使用的編碼必須匹配終端之一。
sys.stdout
底層的二進制緩沖區,例如。 sys.stdout.buffer.write("é".encode('utf8'))
。 這當然是比print("é")
更多的樣板。 同樣,使用的編碼必須匹配終端之一。 print()
。 使用open(fn, encoding=...)
作為輸出,進度信息的日志記錄模塊 - 取決於腳本的交互方式,這可能是值得的(誠然,在寫入STDERR時可能會遇到相同的編碼問題)記錄模塊)。 可能還有其他選擇,但我懷疑有更好的選擇。
似乎ubuntu - 取決於版本 - 使用一個或另一個編碼作為默認值,它也可能在shell和python之間有所不同。 通過這個帖子和這個博客 :
因此推薦的方法似乎是告訴你的python實例使用utf-8
作為默認編碼:
通過環境變量設置python源文件的默認編碼:
export PYTHONIOENCODING=utf8
此外,在源文件中,您可以聲明您希望顯式使用的編碼,因此無論環境設置如何,它都應該工作(請參閱此問題+答案 , python文檔和PEP 263 :
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
....
關於python讀取的文件編碼的解釋,您可以在open命令中明確指定它
with open(fname, "rt", encoding="utf-8") as f:
...
並且有一些更具有一些副作用的hackish方式,但是每次都會保存你以明確指定它
import sys
# sys.setdefaultencoding() does not exist, here!
reload(sys) # Reload does the trick!
sys.setdefaultencoding('UTF8')
請在相關的答案和評論中閱讀有關此黑客的警告。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.