python中的编码知识整理汇总


Posted in Python onJanuary 26, 2016

问题

在平时工作中,遇到了这样的错误:

UnicodeDecodeError: 'ascii' codec can't decode byte

想必大家也都碰到过,很常见 。于是决定对python的编码做一个整理和学习。

基础知识

在python2.x中,有两种数据类型,unicode和str,这两个都是basestring的子类

>>> a = '中'
>>> type(a)
<type 'str'>
>>> isinstance(a,basestring)
True
>>> a = u'中'
>>> type(a)
<type 'unicode'>
>>> isinstance(a,basestring)
True

两者的区别,概括来讲,str是字节串,由unicode经过编码(encode)后的字节组成的(好比与python3.x的byte);unicode是对象,才是真正意义上的字符串,由字符组成

>>> a='中文'
>>> len(a)
6
>>> repr(a)
"'\\xe4\\xb8\\xad\\xe6\\x96\\x87'"
>>> b=u'中文'
>>> len(b)
2
>>> repr(b)
"u'\\u4e2d\\u6587'"

控制台和脚本

在linux下的python控制台执行以下命令,所得的结果和执行脚本是不同的

>>> a = u'中文'
>>> repr(a)
"u'\\xe4\\xb8\\xad\\xe6\\x96\\x87'"
>>> b = unicode('中文','utf-8')b)
>>> repr(b)
"u'\\u4e2d\\u6587'"

可以看到,u'中文'初始化的对象a不是我们所期望的,那究竟是什么原因呢?
将python看成是一根管子,管子里头处理的中间过程都是使用unicode的。入口处,全部转成unicode;出口处,再转成目标编码(当然,有例外,处理逻辑中要用到具体编码的情况)。
在控制台执行命令a = u'中文',可以将解释为命令,a = ‘中文'.decode(encode),从而到到unicode对象a。那么这里的encode是什么呢?对于控制台来说,就是标准输入,即sys.stdin.encoding

>>> sys.stdin.encoding
'ISO-8859-1'

我的这边控制台默认的编码是ISO-8859-1,故a = u'中文' <=> a = '中文'.decode('ISO-8859-1')
这里的'中文'是控制台理解的,即使根据终端编码方式编码后的字节码,对于utf-8编码的终端,'中文'='\\xe4\\xb8\\xad\\xe6\\x96\\x87'

>>> a='中文'.decode('ISO-8859-1') 
>>> repr(a)
"u'\\xe4\\xb8\\xad\\xe6\\x96\\x87'"

那如何修改此编码值呢,设置为什么呢?在linux环境中设置环境变量方法如下,具体设置什么只要与终端编码方式一直即可

export PYTHONIOENCODING=UTF-8

总结

重新回到最初的那个问题,造成问题的原因是没有搞清楚unicode和str的区别,将两者进行了混用。

>>> a = '中文'
>>> a.encode('gbk')
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)

以上的对象a其实是str,即字节码,若终端是utf-8编码的话,那么a就是用utf-8 encode的字节码。a.encode('gbk') 等价于a.decode(encoding).encode('gbk'),即先将字节码解码为unicode字符,然后再encode为字节码。unicode对象作为中转站。那么这里的encoding是什么呢?

>>> import sys
>>> sys.getdefaultencoding()
'ascii'

默认是ascii,这正是错误为什么报无法用ascii解码的原因

>>> reload(sys)
<module 'sys' (built-in)>
>>> sys.setdefaultencoding('utf-8')
>>> a = '中文'
>>> repr(a)
"'\\xe4\\xb8\\xad\\xe6\\x96\\x87'"
>>> a.encode('gbk')
'\xd6\xd0\xce\xc4'

将默认编码改为utf-8,即可。不鼓励对str使用encode方法,因为其中隐式对str进行了解码。decode只对str,encode只对unicode,一切decode/encode都显示指定编码方式。

Python 相关文章推荐
python控制台英汉汉英电子词典
Apr 23 Python
几个提升Python运行效率的方法之间的对比
Apr 03 Python
利用Python的装饰器解决Bottle框架中用户验证问题
Apr 24 Python
Sanic框架流式传输操作示例
Jul 18 Python
pandas.DataFrame的pivot()和unstack()实现行转列
Jul 06 Python
Python列表原理与用法详解【创建、元素增加、删除、访问、计数、切片、遍历等】
Oct 30 Python
使用卷积神经网络(CNN)做人脸识别的示例代码
Mar 27 Python
Python文本文件的合并操作方法代码实例
Mar 31 Python
Tensorflow安装问题: Could not find a version that satisfies the requirement tensorflow
Apr 20 Python
Python 使用xlwt模块将多行多列数据循环写入excel文档的操作
Nov 10 Python
python工具dtreeviz决策树可视化和模型可解释性
Mar 03 Python
python运行脚本文件的三种方法实例
Jun 25 Python
在MAC上搭建python数据分析开发环境
Jan 26 #Python
python黑魔法之编码转换
Jan 25 #Python
Python编程中对文件和存储器的读写示例
Jan 25 #Python
Python开发如何在ubuntu 15.10 上配置vim
Jan 25 #Python
详解Python验证码识别
Jan 25 #Python
Python网站验证码识别
Jan 25 #Python
谈谈Python进行验证码识别的一些想法
Jan 25 #Python
You might like
常用星际术语索引(新手指南)
2020/03/04 星际争霸
php中看实例学正则表达式
2006/12/25 PHP
php+highchats生成动态统计图
2014/05/21 PHP
php实现utf-8转unicode函数分享
2015/01/06 PHP
ThinkPHP实现分页功能
2017/04/28 PHP
javascript之锁定表格栏位
2007/06/29 Javascript
两个比较有用的Javascript工具函数代码
2010/02/17 Javascript
Jquery.TreeView结合ASP.Net和数据库生成菜单导航条
2010/08/27 Javascript
JavaScript中的16进制字符(改进)
2011/11/21 Javascript
jquery 3D 标签云示例代码
2014/06/12 Javascript
jquery向上向下取整适合分页查询
2014/09/06 Javascript
js实现多选项切换导航菜单的方法
2015/02/06 Javascript
javascript计时器详解
2015/02/28 Javascript
Node.js中Request模块处理HTTP协议请求的基本使用教程
2016/03/31 Javascript
JS回调函数简单用法示例
2017/02/09 Javascript
实现div内部滚动条滚动到底部和顶部的代码
2017/11/15 Javascript
vue移动端下拉刷新和上拉加载的实现代码
2018/09/08 Javascript
微信小程序获取位置展示地图并标注信息的实例代码
2019/09/01 Javascript
Node Express用法详解【安装、使用、路由、中间件、模板引擎等】
2020/05/13 Javascript
ant design 日期格式化的实现
2020/10/27 Javascript
Vue-router中hash模式与history模式的区别详解
2020/12/15 Vue.js
使用Python的Flask框架表单插件Flask-WTF实现Web登录验证
2016/07/12 Python
深入理解Django中内置的用户认证
2017/10/06 Python
Django实现分页功能
2018/07/02 Python
Python大数据之网络爬虫的post请求、get请求区别实例分析
2019/11/16 Python
解决pymysql cursor.fetchall() 获取不到数据的问题
2020/05/15 Python
手把手教你用Django执行原生SQL的方法
2021/02/18 Python
纯css3实现的动画按钮的实例教程
2014/11/17 HTML / CSS
Canvas系列之滤镜效果
2019/02/12 HTML / CSS
医学专业五年以上个人求职信
2013/12/03 职场文书
粗加工管理制度
2014/02/04 职场文书
中学教师自我鉴定
2014/02/07 职场文书
遥感技术与仪器求职信
2014/02/22 职场文书
幼儿园小班家长寄语
2014/04/02 职场文书
教师作风建设剖析材料
2014/10/11 职场文书
小兵张嘎电影观后感
2015/06/03 职场文书