我们常用的文件编码一般有两种:utf-8 、gb2312,早期的 Windows 系统的默认编码为 gb2312 ,所以在读写文件时会遇到乱码。如果是人眼来判断,出现乱码换个编码打开就可以了。但如果想让程序自己判断,然后根据不同的编码打开文件,此时就比较麻烦了。
Python 的 PyPI 上有一个第三方的库 chardet 可以判断编码类型,使用前用 pip 下载下来:
C:\Users\hyang0>pip install chardetCollecting chardetDownloading chardet-5.1.0-py3-none-any.whl (199 kB)---------------------------------------- 199.1/199.1 kB 417.0 kB/s eta 0:00:00Installing collected packages: chardetSuccessfully installed chardet-5.1.0
chardet 库安装好后,在 python 的 scripts 目录会多出一个命令行工具,这个命令行工具可以手动验证文件编码类型:
c:\autox>where chardetectC:\Python\Python311\Scripts\chardetect.exec:\autox>chardetect gb2312.ini utf-8.inigb2312.ini: GB2312 with confidence 0.99utf-8.ini: utf-8 with confidence 0.99
我提前准备了两个不同编码的文件,这两个文件是使用 iconv 对 utf-8 文件转码生成的:
$ cat autox.ini | iconv -f utf-8 -t gb2312 > gb2312.ini$ cat gb2312.ini | iconv -f gb2312 -t utf-8 > utf-8.ini$ diff -up utf-8.ini autox.ini$ md5sum -t utf-8.ini autox.ini123a2c53ccc34d44905aa9461bae46ee utf-8.ini123a2c53ccc34d44905aa9461bae46ee autox.ini
在 python 交互模式可以验证 chardet 的用法:
C:\Users\hyang0>pythonPython 3.11.0 (main, Oct 24 2022, 18:26:48) [MSC v.1933 64 bit (AMD64)] on win32>>> f = r'c:\autox\gb2312.ini'>>> fd = open(f, 'rb')>>> chardet.detect(s){'encoding': 'GB2312', 'confidence': 0.99, 'language': 'Chinese'}
我们可以将其包装成判断文件编码的函数,方便在打开文本文件前先获得编码。
#!python3import chardetdef check_encoding(file_name):'''返回:utf-8 或者 GB2312'''with open(file_name, 'rb') as fd:byte = fd.read(1024*8)encoding = chardet.detect(byte)return encoding.get('encoding')if __name__ == '__main__':f1 = r'c:\autox\utf-8.ini'f2 = r'c:\autox\gb2312.ini'print(check_encoding(f1))print(check_encoding(f2))with open(f1, mode='r', encoding=check_encoding(f1)) as f:s = f.read()with open(f2, mode='r', encoding=check_encoding(f2)) as f:s = f.read()
当使用错误的编码打开文件读取文件时,read() 函数会报错:
Traceback (most recent call last):File "d:\pyst\encode_test.py", line 19, in <module>s = f.read()^^^^^^^^UnicodeDecodeError: 'gb2312' codec can't decode byte 0x87 in position 20: illegal multibyte sequence
python3 默认使用 utf-8 读写文件,当需要更改编码时,要在 open 函数中指明编码类型。
全文完。
如果转发本文,文末务必注明:“转自微信公众号:生有可恋”。
文章转载自生有可恋,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




