python解决汉字编码问题:Unicode Decode Error


Posted in Python onJanuary 19, 2017

前言

最近由于项目需要,需要读取一个含有中文的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还不了解的小伙伴,可以看之前的这篇文章关于字符串和编码

那么必须对下面这三个概念有所了解:

  1. ascii只能表示数字、英文字母和一些特殊符号,不能表示汉字
  2. unicode和utf-8都可以表示汉字,unicode是固定长度,utf-8是可变长度
  3. 内存中存储方式一般为unicode,而磁盘文件存储方式一般为utf-8,因为utf-8可以节约存储空间

那么python的默认编码是什么?

>>> import sys
>>> sys.getdefaultencoding()
'ascii'
>>> reload(sys)
<module 'sys' (built-in)>
>>> sys.setdefaultencoding('utf-8')
>>> sys.getdefaultencoding()
'utf-8'

python的默认编码是ascii,可以通过sys.setdefaultencoding('utf-8')函数设置python的默认编码。

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的时候都会报错,牢记下面的规则:

  1. unicode => encode(‘合适的编码') => str
  2. str => decode(‘合适的编码') => unicode

还有一种简单的方式,就是在文件头设置编码,可以省去很多麻烦:

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工作原理。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

Python 相关文章推荐
python将html转成PDF的实现代码(包含中文)
Mar 04 Python
Python中if __name__ == &quot;__main__&quot;详细解释
Oct 21 Python
Python脚本文件打包成可执行文件的方法
Jun 02 Python
Python简明入门教程
Aug 04 Python
python 写入csv乱码问题解决方法
Oct 23 Python
python制作小说爬虫实录
Aug 14 Python
Python解决N阶台阶走法问题的方法分析
Dec 28 Python
对pandas通过索引提取dataframe的行方法详解
Feb 01 Python
Python assert语句的简单使用示例
Jul 28 Python
vscode 配置 python3开发环境的方法
Sep 19 Python
python能自学吗
Jun 18 Python
JupyterNotebook 输出窗口的显示效果调整实现
Sep 22 Python
Python 3.x 连接数据库示例(pymysql 方式)
Jan 19 #Python
Python爬取网易云音乐上评论火爆的歌曲
Jan 19 #Python
一步步教你用Python实现2048小游戏
Jan 19 #Python
python 开发的三种运行模式详细介绍
Jan 18 #Python
Python 3中的yield from语法详解
Jan 18 #Python
Python中的字符串操作和编码Unicode详解
Jan 18 #Python
关于Python中异常(Exception)的汇总
Jan 18 #Python
You might like
一段防盗连的PHP代码
2006/12/06 PHP
php trim 去除空字符的定义与语法介绍
2010/05/31 PHP
PHP命名空间(Namespace)的使用详解
2013/05/04 PHP
php简单实现MVC
2015/02/05 PHP
使用js判断控件是否获得焦点
2014/01/03 Javascript
jquery的trigger和triggerHandler的区别示例介绍
2014/04/20 Javascript
JavaScript对象之深度克隆介绍
2014/12/08 Javascript
Bootstrap每天必学之表单
2015/11/23 Javascript
获取当前月(季度/年)的最后一天(set相关操作及应用)
2016/12/27 Javascript
Vue Element 分组+多选+可搜索Select选择器实现示例
2018/07/23 Javascript
vue路由事件beforeRouteLeave及组件内定时器的清除方法
2018/09/29 Javascript
ajax跨域访问遇到的问题及解决方案
2019/05/23 Javascript
vue封装swiper代码实例解析
2019/10/08 Javascript
JavaScript实现Excel表格效果
2020/02/07 Javascript
怎样使用Python脚本日志功能
2016/08/14 Python
python利用urllib实现爬取京东网站商品图片的爬虫实例
2017/08/24 Python
使用Python+Splinter自动刷新抢12306火车票
2018/01/03 Python
django框架之cookie/session的使用示例(小结)
2018/10/15 Python
最小二乘法及其python实现详解
2020/02/24 Python
Canvas系列之滤镜效果
2019/02/12 HTML / CSS
MATCHESFASHION.COM法国官网:英国奢侈品零售商
2018/01/04 全球购物
雅高酒店中国:Accorhotels.com China
2018/03/26 全球购物
怎样在程序里获得一个空指针
2015/01/24 面试题
启动一个线程是用run()还是start()
2016/12/25 面试题
啤酒销售实习自我鉴定
2013/09/24 职场文书
销售人员职业生涯规划范文
2014/03/01 职场文书
写好自荐信需做到的5要点
2014/03/07 职场文书
舞蹈教育学专业自荐信
2014/06/15 职场文书
单位委托书范本(3篇)
2014/09/18 职场文书
社区党员群众路线教育实践活动心得体会
2014/11/03 职场文书
英语读书笔记
2015/07/02 职场文书
当你焦虑迷茫时,请读读这6句话
2019/07/24 职场文书
想创业成功,需要掌握这些要点
2019/12/06 职场文书
JavaScript offset实现鼠标坐标获取和窗口内模块拖动
2021/05/30 Javascript
Python机器学习实战之k-近邻算法的实现
2021/11/27 Python
MybatisPlus EntityWrapper如何自定义SQL
2022/03/22 Java/Android