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修改Excel数据的实例代码
Nov 01 Python
用Python的Django框架完成视频处理任务的教程
Apr 02 Python
Python中Iterator迭代器的使用杂谈
Jun 20 Python
在Linux命令行终端中使用python的简单方法(推荐)
Jan 23 Python
python中logging库的使用总结
Oct 18 Python
Python用sndhdr模块识别音频格式详解
Jan 11 Python
python实现自动发送邮件发送多人、群发、多附件的示例
Jan 23 Python
python 获取文件下所有文件或目录os.walk()的实例
Apr 23 Python
Python读取excel中的图片完美解决方法
Jul 27 Python
浅谈tensorflow中几个随机函数的用法
Jul 27 Python
详解pandas安装若干异常及解决方案总结
Jan 10 Python
python如何利用traceback获取详细的异常信息
Jun 05 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 第二节 数据类型之转换
2012/04/28 PHP
PHP CURL获取返回值的方法
2014/05/04 PHP
destoon找回管理员密码的方法
2014/06/21 PHP
php接口实现拖拽排序功能
2018/04/23 PHP
PDO::getAvailableDrivers讲解
2019/01/28 PHP
php/JS实现的生成随机密码(验证码)功能示例
2019/06/06 PHP
JAVASCRIPT  THIS详解 面向对象
2009/03/25 Javascript
JS数学函数Exp使用说明
2012/08/09 Javascript
大型JavaScript应用程序架构设计模式
2016/06/29 Javascript
JS实现屏蔽网页右键复制及ctrl+c复制的方法【2种方法】
2016/09/04 Javascript
Angular页面间切换及传值的4种方法
2016/11/04 Javascript
JavaScript 限制文本框不可输入英文单双引号的方法
2016/12/20 Javascript
jquery.tableSort.js表格排序插件使用方法详解
2020/08/12 Javascript
浅谈在fetch方法中添加header后遇到的预检请求问题
2017/08/31 Javascript
详解webpack之scss和postcss-loader的配置
2018/01/09 Javascript
vue刷新和tab切换实例
2018/02/11 Javascript
countup.js实现数字动态叠加效果
2019/10/17 Javascript
vue 弹出遮罩层样式实例
2020/07/22 Javascript
python的tkinter布局之简单的聊天窗口实现方法
2014/09/03 Python
Python格式化日期时间操作示例
2018/06/28 Python
对web.py设置favicon.ico的方法详解
2018/12/04 Python
Python Matplotlib实现三维数据的散点图绘制
2019/03/19 Python
CSS3实现任意图片lowpoly动画效果实例
2017/05/11 HTML / CSS
CSS3打造百度贴吧的3D翻牌效果示例
2017/01/04 HTML / CSS
使用HTML5 Canvas绘制直线或折线等线条的方法讲解
2016/03/14 HTML / CSS
Banggood官网:面向全球客户的综合商城
2017/04/19 全球购物
全世界最美丽的四星和五星级酒店预订:Prestigia.com
2017/11/15 全球购物
牵手50台湾:专为黄金岁月的单身人士而设的交友网站
2021/02/18 全球购物
北大青鸟学生求职信
2013/09/24 职场文书
实习教师自我鉴定
2013/09/27 职场文书
应届生财务管理求职信
2013/11/06 职场文书
工程专业毕业生自荐信范文
2013/12/25 职场文书
人民调解员培训方案
2014/06/05 职场文书
就业协议书怎么填
2014/09/15 职场文书
行风评议整改报告
2014/11/06 职场文书
python文件与路径操作神器 pathlib
2022/04/01 Python