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根据文件大小打log日志
Oct 09 Python
使用Python编写类UNIX系统的命令行工具的教程
Apr 15 Python
Python中使用hashlib模块处理算法的教程
Apr 28 Python
python异常和文件处理机制详解
Jul 19 Python
Python 切分数组实例解析
Nov 07 Python
win10系统Anaconda和Pycharm的Tensorflow2.0之CPU和GPU版本安装教程
Dec 03 Python
numpy按列连接两个维数不同的数组方式
Dec 06 Python
Python全面分析系统的时域特性和频率域特性
Feb 26 Python
Python编程快速上手——Excel到CSV的转换程序案例分析
Feb 28 Python
windows下Pycharm安装opencv的多种方法
Mar 05 Python
Python异常处理机制结构实例解析
Jul 23 Python
用python对excel查重
Dec 07 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入门速成教程
2007/03/19 PHP
php foreach正序倒序输出示例代码
2014/07/01 PHP
PHP判断一个gif图片是否为动态图片的方法
2014/11/19 PHP
CI框架扩展系统核心类的方法分析
2016/05/23 PHP
js绑定事件this指向发生改变的问题解决方法
2013/04/23 Javascript
通过复制Table生成word和excel的javascript代码
2014/01/20 Javascript
jquery实现炫酷的叠加层自动切换特效
2015/02/01 Javascript
jQuery Mobile弹出窗、弹出层知识汇总
2016/01/05 Javascript
全国省市二级联动下拉菜单 js版
2016/05/10 Javascript
jQuery通过deferred对象管理ajax异步
2016/05/20 Javascript
BootstrapValidator不触发校验的实现代码
2016/09/28 Javascript
vue中keep-alive的用法及问题描述
2018/05/15 Javascript
js form表单input框限制20个字符,10个汉字代码实例
2019/04/12 Javascript
Javascript模拟实现new原理解析
2020/03/03 Javascript
微信小程序实现电子签名功能
2020/07/29 Javascript
Vue+scss白天和夜间模式切换功能的实现方法
2021/01/05 Vue.js
Apache如何部署django项目
2017/05/21 Python
Python编程实现的简单Web服务器示例
2017/06/22 Python
python验证码识别教程之灰度处理、二值化、降噪与tesserocr识别
2018/06/04 Python
python pands实现execl转csv 并修改csv指定列的方法
2018/12/12 Python
梅尔频率倒谱系数(mfcc)及Python实现
2019/06/18 Python
Python标准库shutil模块使用方法解析
2020/03/10 Python
python计算Content-MD5并获取文件的Content-MD5值方式
2020/04/03 Python
jupyter note 实现将数据保存为word
2020/04/14 Python
python excel多行合并的方法
2020/12/09 Python
python-图片流传输的思路及示例(url转换二维码)
2020/12/21 Python
css3旋转木马_动力节点Java学院整理
2017/07/12 HTML / CSS
加拿大约会网站:EliteSingles.ca
2018/01/12 全球购物
写出SQL四条最基本的数据操作语句(DML)
2012/12/12 面试题
大学生收银员求职信分享
2014/01/02 职场文书
党员实事承诺书
2014/03/26 职场文书
企业晚会策划方案
2014/05/29 职场文书
医院合作协议书
2014/08/19 职场文书
2014年出纳工作总结与计划
2014/12/09 职场文书
2015学校图书管理员工作总结
2015/05/11 职场文书
vue本地构建热更新卡顿的问题“75 advanced module optimization”完美解决方案
2022/08/05 Vue.js