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的Flask框架中验证注册用户的Email的方法
Sep 02 Python
python制作最美应用的爬虫
Oct 28 Python
Python实现压缩与解压gzip大文件的方法
Sep 18 Python
numpy返回array中元素的index方法
Jun 27 Python
基于Django框架利用Ajax实现点赞功能实例代码
Aug 19 Python
浅谈python的输入输出,注释,基本数据类型
Apr 02 Python
python pycharm的安装及其使用
Oct 11 Python
python解释器pycharm安装及环境变量配置教程图文详解
Feb 26 Python
Keras设定GPU使用内存大小方式(Tensorflow backend)
May 22 Python
python上selenium的弹框操作实现
Jul 13 Python
python进行OpenCV实战之画图(直线、矩形、圆形)
Aug 27 Python
python基于opencv 实现图像时钟
Jan 04 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用正则表达式匹配URL的简单方法
2013/11/12 PHP
php文字水印和php图片水印实现代码(二种加水印方法)
2013/12/25 PHP
PHP类继承 extends使用介绍
2014/01/14 PHP
PHP中对于浮点型的数据需要用不同的方法解决
2014/03/11 PHP
一组PHP加密解密函数分享
2014/06/05 PHP
linux下使用crontab实现定时PHP计划任务失败的原因分析
2014/07/05 PHP
php判断用户是否手机访问代码
2015/06/08 PHP
laravel框架中路由设置,路由参数和路由命名实例分析
2019/11/23 PHP
JavaScript 常用函数
2009/12/30 Javascript
基于jquery实现的鼠标拖拽元素复制并写入效果
2011/08/23 Javascript
Javascript动态引用CSS文件的2种方法介绍
2014/06/06 Javascript
详解JavaScript的回调函数
2015/11/20 Javascript
Nodejs中session的简单使用及通过session实现身份验证的方法
2016/02/04 NodeJs
javascript实现瀑布流动态加载图片原理
2016/08/12 Javascript
xtemplate node.js 的使用方法实例解析
2016/08/22 Javascript
利用JS判断鼠标移入元素的方向
2016/12/11 Javascript
JavaScript原型继承_动力节点Java学院整理
2017/06/30 Javascript
Angular4学习之Angular CLI的安装与使用教程
2018/01/04 Javascript
详解使用create-react-app快速构建React开发环境
2018/05/16 Javascript
Layui Table js 模拟选中checkbox的例子
2019/09/03 Javascript
element跨分页操作选择详解
2020/06/29 Javascript
JavaScript的一些小技巧分享
2021/01/06 Javascript
Python中的pprint折腾记
2015/01/21 Python
Python实现的异步代理爬虫及代理池
2017/03/17 Python
python爬取各类文档方法归类汇总
2018/03/22 Python
python 去除二维数组/二维列表中的重复行方法
2019/01/23 Python
Python通过递归获取目录下指定文件代码实例
2019/11/07 Python
python GUI库图形界面开发之PyQt5滑块条控件QSlider详细使用方法与实例
2020/02/28 Python
python 使用cx-freeze打包程序的实现
2020/03/14 Python
Pytorch 高效使用GPU的操作
2020/06/27 Python
Selenium之模拟登录铁路12306的示例代码
2020/07/31 Python
营销总监岗位职责范本
2014/02/26 职场文书
运动会演讲稿
2014/05/07 职场文书
微信搭讪开场白
2015/05/28 职场文书
Python Numpy之linspace用法说明
2021/04/17 Python
oracle删除超过N天数据脚本的方法
2022/02/28 Oracle