Python Unicode編碼混亂 :來自大洋彼岸的怨念
Unicode
已經解決了很多問題。知曉
ISO-8859-*和
CP437帶來的混亂
(當然對於非西方語言來說更糟糕)
的人都可以證明這一點。當然,這些天他們正在做一項有的益工作——編碼表情符號。除表情符號之外,一切並不那麼順暢。今日
Python 3帶來的痛苦更是一言難盡。
Python
決定將
Unicode完全集成到語言中。聽起來很不錯吧?
但眾多問題也隨之而來。
例如,將帶有智能引號的「播客」標題轉為以
ASCII編碼會引致
python錯誤,導致
gPodder(
一款開源的播客接收器,採用
Python
和
PyGTK
開發,可幫助管理播客
RSS
供稿,並自動下載所需要的播客資料
)
經常通過回溯退出。接著
pexpect
文檔會告訴你用
logfile = sys.stdout
來顯示與虛擬終端的交互。
就是這個在這些天引發了一個錯誤
。文件名的處理可謂糟糕透頂。我最近處理了
20
年前當
UTF-8還未成為文件名標準時的數據。這些文件名在
UNIX上仍然有效,可以用
tar命令進行壓縮或解壓。但當你試圖將文件名以字元串的形式存儲,編碼錯誤便接踵而至。要想讓
Python程序正確地支持所有有效的
Unix文件名,必須使用「
bytes」而不是字元串,這可真夠煩人的。所有
Python程序正確的幾率又能達到多少呢?我敢打賭,不會高的。
我最近正在處理
mtree生成的數據,它使用八進位轉義來處理文件名中的特殊字元。我認為這對於
Python會很容易。結果
…
許多錯誤的解答
甚至存在更多錯誤的解答
第二個鏈接提到了一個未記錄的函數——
codecs.escape_decode
,可正確解決這一問題。我最終不得不這樣做:
而且,無論做什麼,不要輕易寫
if filetype=="file"
——這總被求值為
False,因為
"file"
在邏輯運算時不同於
b"file"
。呃
…好吧,我承認,自己一開始沒注意到,踩過這坑…
因此,如果希望在
Python中正確處理
Unix文件名,你必須:
有一個完全避免
Python字元串的處理路徑。
使用
sys.{stdin,stdout}.buffer
而不是簡單的
sys.stdin/stdout
。
必須將文件名以位元組形式提供給各種函數
。詳情請參閱:「與
os模塊中的其他函數一樣,
scandir()
接受一個
bytes或
str類作為路徑參數,並返回與路徑類型相同的
DirEntry.name
和
DirEntry.path
屬性。但是,強烈建議使用
str類型,因為這樣可以確保
Unicode編碼的文件名得到跨平台支持
(在Windows上,Python 3.3開始,就已經不支持bytes編碼的文件名了)。
」
所以,如果你想跨平台,那就更糟了,因為不能在
Unix上使用
str也不能在
Windows上使用
bytes。
更新:你想在命令行上接收文件名嗎?
我會把
這個爛攤子
交給你的。環境呢?
甚至都不清楚呢
!小編說兩句
:這事兒真不怪Python,題主這種「處理了
20年前當
UTF-8還未成為文件名標準時的數據
」的任務,平時誰會碰到,這種任務當然需要題主對編碼系統足夠了解才能完成了......題主發發牢騷,別怨Python......英文原文:http://changelog.complete.org/archives/9938-the-python-unicode-mess
譯者:盈韜
TAG:Python程序員 |