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 相关文章推荐
Perl中著名的Schwartzian转换问题解决实现
Jun 02 Python
Python 数据结构之队列的实现
Jan 22 Python
Python编程实现生成特定范围内不重复多个随机数的2种方法
Apr 14 Python
Python获取当前页面内所有链接的四种方法对比分析
Aug 19 Python
pandas数据预处理之dataframe的groupby操作方法
Apr 13 Python
Python基于pandas实现json格式转换成dataframe的方法
Jun 22 Python
win10系统下Anaconda3安装配置方法图文教程
Sep 19 Python
Python 安装第三方库 pip install 安装慢安装不上的解决办法
Jun 18 Python
Python插入Elasticsearch操作方法解析
Jan 19 Python
Python中格式化字符串的四种实现
May 26 Python
python安装及变量名介绍详解
Dec 12 Python
基于PyQt5制作一个群发邮件工具
Apr 08 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
Smarty模板快速入门
2007/01/04 PHP
PHP 5.3新特性命名空间规则解析及高级功能
2010/03/11 PHP
php socket通信简单实现
2016/11/18 PHP
javascript下判断一个元素是否存在的代码
2010/03/05 Javascript
基于jQuery UI CSS Framework开发Widget的经验
2010/08/21 Javascript
JS无法捕获滚动条上的mouse up事件的原因猜想
2012/03/21 Javascript
NodeJs中的非阻塞方法介绍
2012/06/05 NodeJs
编写针对IE的JS代码两种编写方法
2013/01/30 Javascript
jQuery实现id模糊查询的小例子
2013/03/19 Javascript
jQuery 获取和设置select下拉框的值实现代码
2013/11/08 Javascript
javascipt:filter过滤介绍及使用
2014/09/10 Javascript
JavaScript判断用户是否对表单进行了修改的方法
2015/03/18 Javascript
利用jQuery实现CheckBox全选/全不选/反选的简单代码
2016/05/31 Javascript
JS判断字符串变量是否含有某个字串的实现方法
2016/06/03 Javascript
JS无缝滚动效果实现方法分析
2016/12/21 Javascript
javascript基于定时器实现进度条功能实例
2017/10/13 Javascript
js中的reduce()函数讲解
2019/01/18 Javascript
Vue清除定时器setInterval优化方案分享
2020/07/21 Javascript
jQuery实现带进度条的轮播图
2020/09/13 jQuery
[06:42]DOTA2每周TOP10 精彩击杀集锦vol.1
2014/06/25 DOTA
python3利用venv配置虚拟环境及过程中的小问题小结
2018/08/01 Python
在python中画正态分布图像的实例
2019/07/08 Python
Python3运算符常见用法分析
2020/02/14 Python
浅谈Django QuerySet对象(模型.objects)的常用方法
2020/03/28 Python
浅谈优化Django ORM中的性能问题
2020/07/09 Python
HTML5页面直接调用百度地图API获取当前位置直接导航目的地的实现代码
2018/03/02 HTML / CSS
美国新蛋IT数码商城:Newegg.com
2016/07/21 全球购物
公司JAVA开发面试题
2015/04/02 面试题
连锁经营管理专业大学生求职信
2013/10/30 职场文书
给导游的表扬信
2014/01/10 职场文书
文字自荐书范文
2014/02/10 职场文书
焦裕禄精神心得体会
2014/09/02 职场文书
公务员上班玩游戏检讨书
2014/09/17 职场文书
毕业证明书
2015/06/19 职场文书
如何书写先进事迹材料?
2019/07/02 职场文书
Python Pandas读取Excel日期数据的异常处理方法
2022/02/28 Python