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开发之字符串string操作方法实例详解
Nov 12 Python
Python抓取框架 Scrapy的架构
Aug 12 Python
一道python走迷宫算法题
Jan 22 Python
python实现二叉查找树实例代码
Feb 08 Python
python3 kmp 字符串匹配的方法
Jul 07 Python
Python读取excel中的图片完美解决方法
Jul 27 Python
python进阶之自定义可迭代的类
Aug 20 Python
django框架cookie和session用法实例详解
Dec 10 Python
Elasticsearch py客户端库安装及使用方法解析
Sep 14 Python
Python如何实现感知器的逻辑电路
Dec 25 Python
详解Python之Scrapy爬虫教程NBA球员数据存放到Mysql数据库
Jan 24 Python
基于Python实现对比Exce的工具
Apr 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.MVC的模板标签系统(三)
2006/09/05 PHP
使用sockets:从新闻组中获取文章(二)
2006/10/09 PHP
php echo()和print()、require()和include()函数区别说明
2010/03/27 PHP
PHP时间相关常用函数用法示例
2020/06/03 PHP
PHP文件打开关闭及读写操作示例解析
2020/08/06 PHP
为指定元素增加样式的js代码
2009/12/09 Javascript
node.js中watch机制详解
2014/11/17 Javascript
node.js中使用socket.io制作命名空间
2014/12/15 Javascript
JS判断是否在微信浏览器打开的简单实例(推荐)
2016/08/24 Javascript
JavaScript callback回调函数用法实例分析
2018/05/08 Javascript
seajs下require书写约定实例分析
2018/05/16 Javascript
JS实现获取进今年第几天是周几的方法分析
2018/06/27 Javascript
nodejs初始化init的示例代码
2018/10/10 NodeJs
详解如何修改 node_modules 里的文件
2020/05/22 Javascript
快速解决vue2+vue-cli3项目ie兼容的问题
2020/11/17 Vue.js
vue-resource 拦截器interceptors使用详解
2021/01/18 Vue.js
[48:28]完美世界DOTA2联赛循环赛FTD vs Magma第二场 10月30日
2020/10/31 DOTA
Python collections模块实例讲解
2014/04/07 Python
Python模拟登录验证码(代码简单)
2016/02/06 Python
Python全局变量用法实例分析
2016/07/19 Python
Python不使用int()函数把字符串转换为数字的方法
2018/07/09 Python
浅谈Python大神都是这样处理XML文件的
2019/05/31 Python
django 微信网页授权登陆的实现
2019/07/30 Python
Python3.6+selenium2.53.6自动化测试_读取excel文件的方法
2019/09/06 Python
Python常用数据类型之间的转换总结
2019/09/06 Python
html5 sessionStorage会话存储_动力节点Java学院整理
2017/07/06 HTML / CSS
理肤泉美国官网:La Roche-Posay
2018/01/17 全球购物
服装厂厂长职责
2013/12/16 职场文书
体育教育专业自荐信范文
2013/12/20 职场文书
自主招生推荐信范文
2014/05/10 职场文书
运动会加油稿100字
2014/09/19 职场文书
2014年依法行政工作总结
2014/11/19 职场文书
2014年林业工作总结
2014/12/05 职场文书
幼儿园教师求职信
2015/03/20 职场文书
教师考核鉴定意见
2015/06/05 职场文书
Win11怎么添加用户?Win11添加用户账户的方法
2022/07/15 数码科技