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多线程扫描端口示例
Jan 16 Python
python实现simhash算法实例
Apr 25 Python
pycharm 使用心得(二)设置字体大小
Jun 05 Python
初步解析Python中的yield函数的用法
Apr 03 Python
python通过索引遍历列表的方法
May 04 Python
Django框架 查询Extra功能实现解析
Sep 04 Python
Python 切分数组实例解析
Nov 07 Python
手把手教你进行Python虚拟环境配置教程
Feb 03 Python
Python中logging日志的四个等级和使用
Nov 17 Python
python 下载文件的几种方式分享
Apr 07 Python
python异常中else的实例用法
Jun 15 Python
Pandas自定义选项option设置
Jul 25 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
jq的get传参数在utf-8中乱码问题的解决php版
2008/07/23 PHP
php 创建以UNIX时间戳命名的文件夹(示例代码)
2014/03/08 PHP
PHP实现根据银行卡号判断银行
2015/04/29 PHP
php自动给网址加上链接的方法
2015/06/02 PHP
php组合排序简单实现方法
2016/10/15 PHP
web 页面分页打印的实现
2009/06/22 Javascript
location对象的属性和方法应用(解析URL)
2013/04/12 Javascript
javascript获取网页各种高宽及位置的方法总结
2016/07/27 Javascript
把多个JavaScript函数绑定到onload事件处理函数上的方法
2016/09/04 Javascript
Mac下使用charles遇到的问题以及解决办法
2017/01/10 Javascript
Canvas实现动态的雪花效果
2017/02/13 Javascript
基于JS对象创建常用方式及原理分析
2017/06/28 Javascript
php register_shutdown_function函数详解
2017/07/23 Javascript
理解javascript async的用法
2017/08/22 Javascript
angular.extend方法的具体使用
2017/09/14 Javascript
vue使用 better-scroll的参数和方法详解
2018/01/25 Javascript
详解vue-cli官方脚手架配置
2018/07/20 Javascript
Javascript原型链及instanceof原理详解
2020/05/25 Javascript
JQuery Ajax如何实现注册检测用户名
2020/09/25 jQuery
JavaScript实现原型封装轮播图
2020/12/27 Javascript
Python实现同时兼容老版和新版Socket协议的一个简单WebSocket服务器
2014/06/04 Python
Python中实现常量(Const)功能
2015/01/28 Python
Python实现批量将word转html并将html内容发布至网站的方法
2015/07/14 Python
详解用Python处理HTML转义字符的5种方式
2017/12/27 Python
Python OS模块实例详解
2019/04/15 Python
Python中函数参数匹配模型详解
2019/06/09 Python
python+selenium 鼠标事件操作方法
2019/08/24 Python
Python3.6安装卸载、执行命令、执行py文件的方法详解
2020/02/20 Python
python如何求100以内的素数
2020/05/27 Python
戴森比利时官方网站:Dyson BE
2020/10/03 全球购物
西安当代医院管理研究院笔试题
2015/12/11 面试题
2013的个人自我评价
2013/12/26 职场文书
大众服装店创业计划书范文
2014/01/01 职场文书
副总经理任命书
2014/06/05 职场文书
2014教师“四风问题”对照检查材料思想汇报
2014/09/16 职场文书
python基础之类属性和实例属性
2021/10/24 Python