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 list 合并连接字符串的方法
Mar 09 Python
Python中捕捉详细异常信息的代码示例
Sep 18 Python
通过C++学习Python
Jan 20 Python
在Python的Django框架中用流响应生成CSV文件的教程
May 02 Python
Python正则抓取网易新闻的方法示例
Apr 21 Python
Python实现的朴素贝叶斯算法经典示例【测试可用】
Jun 13 Python
Python访问MongoDB,并且转换成Dataframe的方法
Oct 15 Python
Python安装selenium包详细过程
Jul 23 Python
python实现用类读取文件数据并计算矩形面积
Jan 18 Python
浅谈pycharm导入pandas包遇到的问题及解决
Jun 01 Python
python cookie反爬处理的实现
Nov 01 Python
详解Python中openpyxl模块基本用法
Feb 23 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
生成php程序的php代码
2008/04/07 PHP
php获取url字符串截取路径的文件名和扩展名的函数
2010/01/22 PHP
在PHP中养成7个面向对象的好习惯
2010/07/17 PHP
Google Voice 短信发送接口PHP开源版(2010.5更新)
2010/07/22 PHP
PHP基础知识回顾
2012/08/16 PHP
php实现mysql数据库操作类分享
2014/02/14 PHP
PHP实现绘制二叉树图形显示功能详解【包括二叉搜索树、平衡树及红黑树】
2017/11/16 PHP
javascript GUID生成器实现代码
2009/10/31 Javascript
js 函数的执行环境和作用域链的深入解析
2009/11/01 Javascript
JavaScript CSS修改学习第三章 修改样式表
2010/02/19 Javascript
javascript动画之圆形运动,环绕鼠标运动作小球
2010/07/20 Javascript
Jquery为a标签的href赋值实现代码
2013/05/03 Javascript
使用jQuery时Form表单元素ID和name命名大忌
2014/03/06 Javascript
jquery实现个人中心导航菜单效果和美观都非常不错
2014/09/02 Javascript
js对象继承之原型链继承实例
2015/01/10 Javascript
js中常用的Tab切换效果(推荐)
2016/08/30 Javascript
浅谈node中的exports与module.exports的关系
2017/08/01 Javascript
认识jQuery的Promise的具体使用方法
2017/10/10 jQuery
JS如何获取地址栏的参数实例讲解
2018/10/06 Javascript
[46:32]Fnatic vs OG 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
python中(str,list,tuple)基础知识汇总
2018/02/20 Python
python定时关机小脚本
2018/06/20 Python
Python中分支语句与循环语句实例详解
2018/09/13 Python
对python中Json与object转化的方法详解
2018/12/31 Python
python交互界面的退出方法
2019/02/16 Python
解析PyCharm Python运行权限问题
2020/01/08 Python
Python使用Pandas库常见操作详解
2020/01/16 Python
Python3 实现爬取网站下所有URL方式
2020/01/16 Python
Perry Ellis官网:美国男士品味服装
2016/12/09 全球购物
英国最大的在线时尚眼镜店:Eyewearbrands
2019/03/12 全球购物
亮化工程实施方案
2014/03/17 职场文书
移交协议书
2014/08/19 职场文书
小学六年级毕业感言
2015/07/30 职场文书
Spring Security使用单点登录的权限功能
2022/04/03 Java/Android
Java实现扫雷游戏详细代码讲解
2022/05/25 Java/Android
Java服务调用RestTemplate与HttpClient的使用详解
2022/06/21 Java/Android