Python文本文件读写操作时的字符编码问题
说明1:文本文件的字符编码问题只存在t模式中,如:open('a.txt', mode='rt')
编码(encode):
我们输入的任何字符想要以文件(如.txt)的形式保存在计算机的硬盘上, 必须先按照一定的规则编成计算机认识的二进制后,才能存在电脑硬盘上。这种规则有GBK,utf-8等。
解码(decode):
同理,计算机硬盘上文件,想要正确显示在电脑屏幕上,也必须先按照一定的规则从计算机硬盘上通过解码,把二进制数据解码成字符,我们才能在电脑屏幕上看到。并且,如果,解码的方式不对,就会出现乱码。如,文件是以GBK的形式编码的,那解码也必须使用GBK解码,如果使用UTF-8解码,则会出现乱码。
文件的读
Python中通过open()的方式,对文本文件作读和写的操作
现在,我有两个文件:
- test1_gbk.txt
- test2_utf-8.txt
两者的相同点是:保存的内容相同(“中国你好”)
两者的不同点是:test1_gbk.txt按gbk编码保存在硬盘上,test2_utf-8按utf-8编码保存在硬盘上
现在做个测试
测试环境:
- win10
- Python3.7
- Pycharm
1,读test1_gbk.txt
f = open('test1_gbk.txt', 'r')
s = f.read()
f.close()
print(s)
结果:你好中国
2,读test2_utf-8.txt
f = open('test2_utf-8.txt', 'r')
s = f.read()
f.close()
print(s)
结果报错:UnicodeDecodeError: 'gbk' codec can't decode byte 0xbd in position 14: incomplete multibyte sequence
补充:如果文件中写的不是“你好中国”,而是其他的中文字符,可能不会报错但会出现乱码的现象。
为什么?
我们通过查看open() 的函数的解释可以发现 open() 是有很多默认参数的,如,encoding
open(file, mode='r', buffering=None, encoding=None, errors=None, newline=None, closefd=True)
......
#encoding解释如下:
encoding is the name of the encoding used to decode or encode the
file. This should only be used in text mode. The default encoding is
platform dependent, but any encoding supported by Python can be
passed. See the codecs module for the list of supported encodings.
就是说,encoding其实具有编码和解码的两个功能。
我的理解是:
- 当open用来读取文件时,encoding的作用是解码;
- 当open用来写文件时,encoding的作用是编码。
另外,解码或编码时,encodng的默认方式到底是gbk还是UTF-8,这个取决于我们的操作系统,在windows上是默认的gbk。
因此,上面的第二个测试结果,出现报错的提示,想要不报错,只要添加 encoding = 'utf-8'即可
f = open('test2_utf-8.txt', 'r', encoding = 'utf-8')
s = f.read()
f.close()
print(s)
另外知道这点以后,对于test1_gbk.txt 来说,encoding = ‘gbk’ 存在与否是没有影响的
文件的写
- 以上是文件的读,文件的写同理
- 不同的是此时,encoding的功能是编码
- 通过下面的代码创建的文件test3.txt是通过GBK的方式编码保存的文件
f = open('test3.txt', 'w')
s = '中国你好'
f.write(s)
f.close()
- 如果想要给你的朋友发送一个.txt文件,但是他的笔记本是苹果的mac,你发的文件必须是ufd-8编码的文本文件,否则对方打开是就会出现乱码,因为mac默认的解码是按 utf-8
- 如果,你的笔记本也是mac,那没有关系,因为mac默认的写的文本文件的编码是utf-8
- 但如果你是windows用户,你就必须注意。
f = open('test4.txt', 'w', encoding = 'utf-8')
s = '中国你好'
f.write(s)
f.close()
- 在windows上,上面这种方式就创建了一个以utf-8编码的文件 test4.txt