Last Updated: 2024-05-09 13:36:33 Thursday
-- TOC --
UTF-8编码格式的文件已经几乎统一天下,但是Python在读取的时候,还是有可能遇到意外。
用Python读取UTF-8文本文件很简单,一行代码就搞定,如下:
with open(filename) as f:
...
但这样写的代码有个问题,在调用open函数的时候,没有指定encoding参数。为什么要指定encoding参数?默认难道不是UTF-8吗?
是的,不一定!在Linux平台下,open函数的encoding参数基本上默认都是UTF-8,但在Windows平台下就不一定了。在读取文本文件的时候,如果open()函数没有指定encoding,python3会选取代码所运行的计算机操作系统的默认编码作为open()函数的编码方式。
当使用非UTF-8的方式读取UTF-8文件时,可能的错误是这样的:
UnicodeDecodeError: \
'gbk' codec can't decode byte 0xae in position 54: illegal multibyte sequence
...
UnicodeDecodeError: \
'utf-8' codec can't decode byte 0xb5 in position 2: invalid start byte
用Python查看系统默认charset:
$ python3 -q # Ubuntu
>>> import locale
>>> locale.getpreferredencoding(False)
'UTF-8'
C:\Users\xinlin>python -q # Win10
>>> import locale
>>> locale.getpreferredencoding(False)
'cp936'
另一个接口:
sys.getfilesystemencoding()
,用来查看OS文件系统所使用的encoding,即用什么编码方式,将unicode的文件名转换成OS支持的文件名。Window系统下,这个接口返回的是UTF-8。
如上所述,open函数没有设置encoding时,会使用OS的默认编码,这就带来了不确定性。例如Windows中文系统,默认是GBK编码;而繁体中文的Windows系统,默认是Big5编码。
如果代码读取的文件是UTF-8编码,为了让你的Python程序能够有一定的跨平台运行的能力,建议给open函数统一加上encoding='utf-8'
。
with open(filename, encoding='utf-8') as f:
...
这样做还规避了另外一个蛋疼的问题:如果不加encoding='utf-8'
,你的程序在Windows系统下运行,在读取英文UTF-8文件时很正常,而在读取含有中文的UTF-8文件时,就崩溃!
如果你的程序只读取英文文档,那很OK,但也要意识到,增加中文文档的读取功能,很可能是增加了一个新的feature...
用rb方式读取文件时,就没有必要考虑encoding的问题了。
with open(filename, 'rb') as f:
...
因为这个时候,代码其实是不关心文件内容的编码是什么的,统一按照byte的方式读取和处理。
是的,虽然也许你很确定你的程序要读的文件,都是utf-8格式的,但是一旦不小心出现非utf-8编码的文件,上面的代码也存在崩溃的风险。更安全的代码写法是:
with open(filename, encoding='utf-8') as f:
try:
...
except:
...
指定按utf-8的方式读取文件,但是如果文件不是utf-8,抛出异常。注意,异常不是在调用open的时候抛出,而是在后续read的时候抛出。
You can use the Python UTF-8 Mode to change the default text encoding to UTF-8. You can enable the Python UTF-8 Mode via the
-X utf8
command line option, or thePYTHONUTF8=1
environment variable.
在启动Python的时候,使用命令行参数-X utf8
;或者设置环境变量PYTHONUTF8=1。
本文链接:https://cs.pynote.net/sf/python/202109191/
-- EOF --
-- MORE --