Fold All / Expand All

2017年3月8日 星期三

Python os.listdir() 與 encoding

傷當令人崩潰的問題
Python 的 os.listdir(),如果是給 string,回傳的也是 string
給 Unicode string 時,回的可能是 Unicode string,也有可能是 string…
os.listdir('.') # ['abc']
os.listdir(u'.') # [u'abc']
有非英文
# abc, 你好
os.listdir('.') # ['abc', '\xe4\xbd\xa0\xe5\xa5\xbd']
os.listdir(u'.') # [u'abc', u'\u4f60\u597d']
上述是在 Ubuntu 上,「你好」是用 UTF-8 encoding 寫的,LC_ALL為 en_US.UTF-8 時
如果是在 Windows 10 上呢
# abc, 你好
os.listdir('.') # ['abc', '\xa7A\xa6n'']
os.listdir(u'.') # [u'abc', u'\u4f60\u597d']
好吧,Windows 上不是我們的重點
今天在 Ubuntu 上,把 LC_ALL 改為 en_US.latin1 時
檔名是 UTF-8 encoding 寫的,卻會因為 LC_ALL 而變成
# abc, 你好
os.listdir('.') # ['abc', '\xe4\xbd\xa0\xe5\xa5\xbd']
os.listdir(u'.') # [u'abc', '\xe4\xbd\xa0\xe5\xa5\xbd']
這就是上面提到的,os.listdir() 參數給 Unicode string,但結果有可能是 string 或 Unicode string
而 os.path.isfile() 也會受到相同的影響
# when LC_ALL=en_US.UTF-8
os.path.isfile(u'你好') # True

# when LC_ALL=en_US.latin1
os.path.isfile(u'你好') # UnicodeEncodeError: 
# 'ascii' codec can't encode character u'\xa7' in position 0:
# ordinal not in range(128)
崩潰…
所以遇到 Python 在處理 file 時,有奇怪的 unicode error 的話,先確認一下執行環境的 LC_ALL 吧

沒有留言: