最近在利用 python 读取一个含有汉字的文档时导致出现了乱码,并报出了两个错误,无奈只能上网找寻答案,后通过网友的帮助解决了这个问题,想着总结一下,下面这篇文章就主要介绍了 python 如何解决汉字编码问题,有需要的朋友们可以参考借鉴。
Python 是一种面向对象、解释型计算机程序设计语言,由 Guido van Rossum 于 1989 年底发明,第一个公开发行版发行于 1991 年。Python 语法简洁而清晰,具有丰富和强大的类库。它常被昵称为胶水语言,它能够把用其他语言制作的各种模块(尤其是 C/C++)很轻松地联结在一起。
前言
最近由于项目需要,需要读取一个含有中文的 txt 文档,完了还要保存文件。文档之前是由 base64 编码,导致所有汉字读取显示乱码。项目组把 base64 废弃之后,先后出现两个错误:
- ascii codec can't encode characters in position ordinal not in range 128
- UnicodeDecodeError: 'utf8' codec can't decode byte 0x。
如果对于 ascii、unicode 和 utf-8 还不了解的小伙伴,可以看之前的这篇文章关于 {aa0aa}
那么必须对下面这三个概念有所了解:
那么 python 的默认编码是什么?
- >>> import sys
- >>> sys.getdefaultencoding()
- 'ascii'
- >>> reload(sys)
- <module 'sys' (built-in)>
- >>> sys.setdefaultencoding('utf-8')
- >>> sys.getdefaultencoding()
- 'utf-8'
python 的默认编码是 ascii,可以通过
函数设置 python 的默认编码。
- sys.setdefaultencoding('utf-8')
python 中可以通过 encode 和 decode 的方式改变数据的编码,比如:
- >>> u'汉字'
- u'\u6c49\u5b57'
- >>> u'汉字'.encode('utf-8')
- '\xe6\xb1\x89\xe5\xad\x97'
- >>> u'汉字'.encode('utf-8').decode('utf-8')
- u'\u6c49\u5b57'
我们可以通过这两个函数设置编码。
那么,python 中的 str 是什么类型?
- >>> import binascii
- >>> '汉字'
- '\xba\xba\xd7\xd6'
- >>> type('汉字')
- <type 'str'>
- >>> print binascii.b2a_hex('汉字')
- babad7d6
- >>> print binascii.b2a_hex(u'汉字')
- Traceback (most recent call last):
- File "<stdin>", line 1, in <module>
- UnicodeEncodeError: 'ascii' codec can't encode characters in
- position 0-1: ordinal not in range(128)
- >>> print binascii.b2a_hex(u'汉字'.encode('utf-8'))
- e6b189e5ad97
- >>> print binascii.b2a_hex(u'汉字'.encode('gbk'))
- babad7d6
binascii 是将数据的二进制转换成 ascii,上面的解释是:'汉字'的类型是 str,二进制是 babad7d6,u'汉字'是无法转换成 ascii,这样就报出了开头的第一个错误。解决办法就是把它. encode('utf-8') 成 str 类型。因为我命令行是 windows 默认的 GBK 编码,所有 u'汉字'
的时候,输出结果和'汉字'结果一样。
- .encode('gbk')
总结一下,python 的 str 实际上是 unicode 的一种,python 的默认编码是 ascii,对于非 ascii 转成 ascii 的时候都会报错,牢记下面的规则:
还有一种简单的方式,就是在文件头设置编码,可以省去很多麻烦:
- import sys
- reloads(sys)
- sys.setdefaultencoding('utf-8')
对于第二个问题,是在文件读取的时候出的错。utf-8 的文件有 bom 和无 bom 两种方式,两者的差别好像在 bom 文件比无 bom 文件多了一个头,导致以 utf-8 方式读文件时报错,我先前曾尝试读文件的时候先对有无 bom 进行判断,跳过 bom 文件的头,后来失败了,真尴尬~~。
还得上 google 求助大神,具体的操作方法就是使用 codecs 库来读文件(我猜这个库就是对文件的头进行检测)。
- import codecs
- codecs.open(file_name, "r",encoding='utf-8', errors='ignore')
对于编码问题,一定要懂得 ascii、unicode 和 utf-8 工作原理。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。
来源: