最初難倒你,是因爲你正在運行的Python終端仿真器內的異常(或可能「控制檯窗口」是一個常用術語?)不能顯示所有以Unicode字符。爲了解決這個問題,你需要讓自己擁有一個支持Unicode的終端仿真器,然後確保Python 知道它在支持Unicode的終端仿真器中運行。如果您不知道如何操作,請在superuser.com上提出一個新問題,指定您的操作系統。
我的終端模擬器可以顯示所有的Unicode字符,假設所有必要的字體是可用的,Python知道這一點,所以我能做到這一點,並沒有得到一個異常:
>>> with open("countryCity2.json", "r", encoding="utf-16") as f:
... x = f.read()
...
>>> print(x)
["Xinhua","Ürümqi"]
然而,那不是你唯一的問題。您的輸入文件的編碼已被破壞。 Ãœrümqi
不是任何語言中有意義的字符序列。但是,它符合從傳統編碼轉換爲UTF-8的文本特徵mojibake,然後 - 錯誤地轉換爲Unicode編碼再次。 1個字節,看到如果我們得到一個合法的UTF-8字節序列:
>>> print(x.encode("iso-8859-1").decode("utf-8"))
["Xinhua","Ürümqi"]
「Ürümqi」是一個真正的字,並會振振有詞地出現在結合「Xinhua」我們可以通過1將它進行測試。此外,如果文本不誤轉換後的UTF-8,我們會看到一個例外:
>>> "Ürümqi".encode("iso-8859-1").decode("utf-8")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xdc in position 0:
invalid continuation byte
所以假設得到了證實。
在一個程序,不得不處理了大量的文件,它們的編碼可能會或可能不會被這樣缺胳膊少腿,我會做這樣的事情:我在這裏使用ISO 8859.1編碼
for fname in input_files:
with open(fname, "r", encoding="utf-16") as f:
contents = f.read()
try:
contents = contents.encode("iso-8859-1").decode("utf-8")
except (UnicodeEncodeError, UnicodeDecodeError):
pass
process_file(fname, contents)
而不是,因爲文本是或曾經在編碼中,但是因爲Python的iso-8859-1
編解碼器是從字符U + 0000..U + 00FF到字節0x00..0xFF的標識映射。 (在技術上,這意味着它實現IANA ISO_8859-1:1987代替了原來的ECMA-94:1985的代碼頁,這在離開0x00..0x1F和0x7F..0x9F範圍未定義)即,
>>> "".join(chr(c) for c in range(256)).encode('iso-8859-1') == bytes(range(256))
True
因此,只要有二進制數據被錯誤地轉換爲Unicode,就可以用.encode('iso-8859-1')
恢復原始數據。
注:以上所有代碼片段的Python 3
你確定你知道哪一行失敗嗎? – 2015-03-03 02:47:47
請從該文件的副本中刪除大塊文本,直到找到產生問題的最小可能文件,然後發佈最小可能文件的*十六進制轉儲*。 – zwol 2015-03-03 02:51:29
編碼是大還是小?您正在閱讀的文件是否包含字節順序標記(BOM)? – Frank 2015-03-03 04:13:58