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实现的二维码生成小软件
Jul 11 Python
在Python中操作时间之tzset()方法的使用教程
May 22 Python
Python函数式编程指南(四):生成器详解
Jun 24 Python
python 批量解压压缩文件的实例代码
Jun 27 Python
关于Python 的简单栅格图像边界提取方法
Jul 05 Python
python3 求约数的实例
Dec 05 Python
python Canny边缘检测算法的实现
Apr 24 Python
python解释器安装教程的方法步骤
Jul 02 Python
python集合能干吗
Jul 19 Python
Python如何输出警告信息
Jul 30 Python
Pycharm操作Git及GitHub的步骤详解
Oct 27 Python
彻底解决Python包下载慢问题
Nov 15 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用户指南-cookies部分
2006/10/09 PHP
PHP中查询SQL Server或Sybase时TEXT字段被截断的解决方法
2009/03/10 PHP
解决出现SoapFault (looks like we got no XML document)的问题
2017/06/24 PHP
基于jquery的表格排序
2010/09/11 Javascript
关于js datetime的那点事
2011/11/15 Javascript
如何利用JQuery实现从底部回到顶部的功能
2016/12/27 Javascript
node学习记录之搭建web服务器教程
2017/02/16 Javascript
深入理解AngularJs-scope的脏检查(一)
2017/06/19 Javascript
AngularJS集合数据遍历显示的实例
2017/12/27 Javascript
详解Angularjs 自定义指令中的数据绑定
2018/07/19 Javascript
element-ui 的el-button组件中添加自定义颜色和图标的实现方法
2018/10/26 Javascript
微信小程序自定义弹窗滚动与页面滚动冲突的解决方法
2019/07/16 Javascript
NUXT SSR初级入门笔记(小结)
2019/12/16 Javascript
[01:33]一分钟玩转DOTA2第三弹:DOTA2&DotA快捷操作大对比
2014/06/04 DOTA
Python的批量远程管理和部署工具Fabric用法实例
2015/01/23 Python
Python中用memcached来减少数据库查询次数的教程
2015/04/07 Python
Python程序中用csv模块来操作csv文件的基本使用教程
2016/03/03 Python
删除python pandas.DataFrame 的多重index实例
2018/06/08 Python
python搜索包的路径的实现方法
2019/07/19 Python
一行python实现树形结构的方法
2019/08/09 Python
Python基于requests实现模拟上传文件
2020/04/21 Python
python中spy++的使用超详细教程
2021/01/29 Python
香港最新科技与优质家居产品购物网站:J SELECT
2018/08/21 全球购物
岳父生日宴会答谢词
2014/01/13 职场文书
毕业生自荐书
2014/02/03 职场文书
艺术学院毕业生自我评价
2014/03/02 职场文书
企业总经理助理岗位职责
2014/09/12 职场文书
学术研讨会欢迎词
2015/01/26 职场文书
怎样写离婚协议书
2015/01/26 职场文书
毕业赠语大全
2015/06/23 职场文书
学生会招新宣传语
2015/07/13 职场文书
创业计划书之物流运送
2019/09/17 职场文书
JavaScript嵌入百度地图API的最详细方法
2021/04/16 Javascript
SpringBoot2 参数管理实践之入参出参与校验的方式
2021/06/16 Java/Android
OpenCV图像变换之傅里叶变换的一些应用
2021/07/26 Python
Go 语言中 20 个占位符的整理
2021/10/16 Golang