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 相关文章推荐
paramiko模块安装和使用(远程登录服务器)
Jan 27 Python
Python中的defaultdict模块和namedtuple模块的简单入门指南
Apr 01 Python
浅谈Python中函数的参数传递
Jun 21 Python
Python 多核并行计算的示例代码
Nov 07 Python
python 反向输出字符串的方法
Jul 16 Python
Python装饰器语法糖
Jan 02 Python
python实现烟花小程序
Jan 30 Python
python 实现Flask中返回图片流给前端展示
Jan 09 Python
Anaconda的安装及其环境变量的配置详解
Apr 22 Python
完美解决ARIMA模型中plot_acf画不出图的问题
Jun 04 Python
django使用channels实现通信的示例
Oct 19 Python
python爬虫利用代理池更换IP的方法步骤
Feb 21 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/10/09 PHP
PHP写MySQL数据 实现代码
2009/06/15 PHP
php 生成WML页面方法详解
2009/08/09 PHP
PHPstorm快捷键(分享)
2017/07/17 PHP
PHP常用日期加减计算方法实例小结
2018/07/31 PHP
Yaf框架封装的MySQL数据库操作示例
2019/03/06 PHP
PHP实现的pdo连接数据库并插入数据功能简单示例
2019/03/30 PHP
jquery中dom操作和事件的实例学习 下拉框应用
2011/12/01 Javascript
jquery实现的网页自动播放声音
2014/04/30 Javascript
提交按钮的name='submit'引起的js失效问题及原因
2015/02/25 Javascript
JavaScript中innerHTML,innerText,outerHTML的用法及区别
2015/09/01 Javascript
JS简单随机数生成方法
2016/09/05 Javascript
JS中解决谷歌浏览器记住密码输入框颜色改变功能
2017/02/13 Javascript
JS拉起或下载app的实现代码
2017/02/22 Javascript
JS解决IOS中拍照图片预览旋转90度BUG的问题
2017/09/13 Javascript
vue+iview+less+echarts实战项目总结
2018/02/22 Javascript
React Router v4 入坑指南(小结)
2018/04/08 Javascript
Vue.js实现的计算器功能完整示例
2018/07/11 Javascript
vue.js实现的幻灯片功能示例
2019/01/18 Javascript
基于vue-cli、elementUI的Vue超简单入门小例子(推荐)
2019/04/17 Javascript
用JS实现一个简单的打砖块游戏
2019/12/11 Javascript
python使用scrapy解析js示例
2014/01/23 Python
编写简单的Python程序来判断文本的语种
2015/04/07 Python
Python中的id()函数指的什么
2017/10/17 Python
python requests 测试代理ip是否生效
2018/07/25 Python
对python csv模块配置分隔符和引用符详解
2018/12/12 Python
python开发游戏的前期准备
2019/05/05 Python
python3实现高效的端口扫描
2019/08/31 Python
Python基于Hypothesis测试库生成测试数据
2020/04/29 Python
PyCharm MySQL可视化Database配置过程图解
2020/06/09 Python
recorder.js 基于Html5录音功能的实现
2020/05/26 HTML / CSS
YSL圣罗兰美妆俄罗斯官网:Yves Saint Lauret RU
2020/09/23 全球购物
面临毕业的毕业生自荐书范文
2014/02/05 职场文书
自立自强的名人事例
2014/02/10 职场文书
2014年食品安全工作总结
2014/12/04 职场文书
JavaScript前端面试组合函数
2022/06/21 Javascript