解決Python在windows平臺預設編碼(encoding)為gbk所導致的open()函式報錯及其他編碼問題

ycycorona發表於2018-10-26

注意 以下提到的Python均指的Python3.7

在windows平臺下使用python內建函式 open() 時發現,當不傳遞encoding引數時,會自動採用gbk(cp936)編碼開啟檔案,而當下很大部分檔案的編碼都是UTF-8。

我們當然可以通過每次手動傳參encoding='utf-8',但是略顯冗餘,而且有很多外國的第三方包,裡面呼叫的內建open()函式並沒有提供介面讓我們指定encoding,這就會導致這些包在windows平臺上使用時,常會出現如 "UnicodeDecodeError: 'gbk' codec can't decode byte 0x91 in position 209: illegal multibyte sequence" 的報錯

通過檢視python文件分析原因:

if encoding is not specified the encoding used is platform dependent: locale.getpreferredencoding(False) is called to get the current locale encoding. (For reading and writing raw bytes use binary mode and leave encoding unspecified.)

可以發現當open不傳遞encoding引數時,是預設呼叫locale.getpreferredencoding()方法來獲取當前平臺的“預設編碼型別”,繼續檢視相關文件,發現有兩種方法可以指定windows平臺下Python執行時的“預設編碼型別”。

1. 指定sys.flags.utf8_mode(推薦)

通過執行指令碼是新增命令列引數 -X utf8(注意是跟在python.exe後面的interpreter option,不是跟在要執行指令碼後面的parameters!)

指定sys.flags.utf8_mode引數之後,Python執行時會在很多場景下自動使用utf-8編碼,而不是win預設的gbk(cp936)編碼。

2. 直接重寫_locale(相容老版本)

import _locale
_locale._getdefaultlocale = (lambda *args: ['en_US', 'utf8'])
複製程式碼

python直譯器會取_getdefaultlocale()[1]作為預設編碼型別,重寫後,會改變當前執行環境下的所有模組的預設編碼。

總之,使用以上兩種方法後,windows平臺下,open()函式會預設用utf-8編碼開啟檔案,其實不止open()方法,跨模組、全域性改變python直譯器的預設編碼為utf-8,會帶來很多使用上的便利,而不需要被gbk編碼報錯的噩夢所糾纏。

相關文章