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字符串排序方法
Aug 29 Python
python将每个单词按空格分开并保存到文件中
Mar 19 Python
网红编程语言Python将纳入高考你怎么看?
Jun 07 Python
Python退火算法在高次方程的应用
Jul 26 Python
Python实现根据日期获取当天凌晨时间戳的方法示例
Apr 09 Python
Django对数据库进行添加与更新的例子
Jul 12 Python
Python PyInstaller库基本使用方法分析
Dec 12 Python
使用python实现哈希表、字典、集合操作
Dec 22 Python
Python如何实现邮件功能
May 27 Python
Python模块zipfile原理及使用方法详解
Aug 04 Python
python中的getter与setter你了解吗
Mar 24 Python
Python 全局空间和局部空间
Apr 06 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
给海燕B411配件机起死回生配上件
2021/03/02 无线电
PHP中基本符号及使用方法
2010/03/23 PHP
PHP 验证码的实现代码
2011/07/17 PHP
用javascript来实现动画导航效果的代码
2007/12/16 Javascript
JS高级拖动技术 setCapture,releaseCapture
2011/07/31 Javascript
CSS鼠标响应事件经过、移动、点击示例介绍
2013/09/04 Javascript
使用CSS和jQuery模拟select并附提交后取得数据的代码
2013/10/18 Javascript
判断javascript的数据类型(示例代码)
2013/12/11 Javascript
JS截取url中问号后面参数的值信息
2014/04/29 Javascript
jQuery Chosen通用初始化
2017/03/07 Javascript
js实现放大镜特效
2017/05/18 Javascript
Vue中使用create-keyframe-animation与动画钩子完成复杂动画
2019/04/09 Javascript
nodejs简单抓包工具使用详解
2019/08/23 NodeJs
JavaScript实现沿五角星形线摆动的小圆实例详解
2020/07/28 Javascript
[56:42]VP vs RNG 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/17 DOTA
python实现搜索指定目录下文件及文件内搜索指定关键词的方法
2015/06/28 Python
Python实现多线程抓取网页功能实例详解
2017/06/08 Python
python中使用PIL制作并验证图片验证码
2018/03/15 Python
python3+PyQt5使用数据库窗口视图
2018/04/24 Python
浅谈Python traceback的优雅处理
2018/08/31 Python
使用Python实现企业微信的自动打卡功能
2019/04/30 Python
Flask框架学习笔记之消息提示与异常处理操作详解
2019/08/15 Python
python json 递归打印所有json子节点信息的例子
2020/02/27 Python
Python装饰器实现方法及应用场景详解
2020/03/26 Python
获取CSDN文章内容并转换为markdown文本的python
2020/09/06 Python
Canvas globalCompositeOperation
2018/12/18 HTML / CSS
马来西亚网上花店:FlowerAdvisor马来西亚
2020/01/03 全球购物
Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型
2013/10/30 面试题
大专学生推荐信范文
2013/11/19 职场文书
表彰先进集体通报
2014/01/12 职场文书
亲子读书活动方案
2014/02/22 职场文书
单位租房协议书样本
2014/10/30 职场文书
Python 线程池模块之多线程操作代码
2021/05/20 Python
css布局巧妙技巧之css三角示例的运用
2022/03/16 HTML / CSS
《战锤40K:暗潮》跳票至9月 公布新宣传片
2022/04/03 其他游戏
详解Flutter和Dart取消Future的三种方法
2022/04/07 Java/Android