[python]Python2编码问题
以下内容说的都是 python 2.x 版本
简介
- 基本概念
- Python “帮”你做的事情
- 推荐姿势
1、基本概念
我们看到的输入输出都是‘字符’(characters),计算机(程序)并不能直接处理,需要转化成字节数据(bytes),因为程序只能处理 bytes 数据。
例如:文件、网络传输等,处理的都是 bytes 数据——二进制数字。
1.1 ASCII / Unicode
孤立的 byte 是毫无意义的,所以我们来赋予他们含义。就引入‘字符集’的概念,‘字符集’就是一个码位(code point)对应的一个字符的表。
该表用于赋予 byte 意义。还需要知道一个点:因为 ASCII 字符集支持的字符太少,不能表示各个国家语言中的字符。所以就发明了
Unicode ——万国码,该字符集包含了你能用到的所有的字符。
1.2 Encode / Decode
在 python 中字符串分为两个对象:str
和 unicode
- str: a sequence of bytes
- unicode:a sequence of code point(码位——字符集中的数字)
unicode_obj.encode() ——> bytes ‘编码’(encode)
bytes_obj.decode() ——> unicode ‘解码’(decode)
UTF-8 是最流行的一种对 Unicode 进行传播和存储的编码方式。所以,多用它作为编码方式。
s = 'hello' # str
u = u'你好' # unicode
back_to_bytes = u.encode('utf-8')
back_to_utf8 = back_to_bytes.decode('utf-8') # 或 unicode(s, 'utf-8')
1.3 声明编码
正如前面所说的,计算机只能操作 bytes,所以 Python 在编译原文件的时候,会先把源文件进行编码,默认以‘ASCII’进行编码。这就是为什么如果源文件中带有‘中文’,需要在源文件的起始行声明编码方式。
完成编码后,源码中的所有字符,都变成了 bytes 计算机就可以进行编译和处理了。编译过程:
- 读取文件
- 不同的文件,根据其声明的编码去解析为Unicode
- 转换为UTF-8字符串
- 针对UTF-8字符串,去分词
- 编译,创建Unicode对象(Python解释器处理)
根据这个过程,在自己的代码中也应该按照这个逻辑处理,意思是:
- 接收外部数据时,统一转化为Unicode
- 代码内部处理的都是Unicode
- 输出时统一转化为UTF-8(网络数据传输、文本输出)
参考:PEP 263 -- Defining Python Source Code Encodings
1.4 小结
- 程序中所有的输入和输出均为 byte
- 世界上的文本需要比 256 更多的符号来表现(ASCII是不够的)
- 你的程序必须能够处理 byte 和 unicode
- byte 流中不会包含编码信息(编码信息会在:文件的开头、协议中等地方声明)
Content-Type:text/html; charset=UTF-8
- 指明的编码有可能是错误的(出现乱码)
2、python “帮”你做的事情
在 python 中处理编码问题,会出现很多问题,这里就不一一列举。
这些问题大都是使用了不匹配的编码方式进行解码、编码造成的。而 python 为了语法更加简介,在一些内置方法中,使用了一些隐性转换。这种隐形的转换带了的便捷的同时也会带来一些非预期的错误。下面就一一道来。
2.1 a = "abc" + u"bcd"
a = "abc" + u"bcd"
,Python 会如此转换 "abc".decode(sys.getdefaultencoding()) 然后将两个 Unicode 字符合并。
2.2 两个内建方法str()
和unicode()
,
- str:something.encode(sys.getdefaultencoding())
- unicode:something.decode(sys.getdefaultencoding())
sys.getdefaultencoding()
默认为:ASCII,这就是为什么str(u'中文')
和unicode('中文')
分别会报错:UnicodeEncodeError和UnicodeDecodeError。因为ASCII编码方式,编码/解码不了中文(支持的字符有限)。
2.3 print
函数
print
函数,会对输出的内容进行编码,这是因为:所谓的输出,也是从一个程序到另外一个程序。程序之间的交互都是都是传递 bytes。比方说print
,就是把数据传递给 终端 ,终端也是个程序,所以print
函数就把需要输出的内容编码成了 bytes,采用那种编码方式,就是
由sys.stdout.encoding
参数决定的。
在交互环境下(python、ipython)输入的数据的编码则由sys.stdin.encoding
参数决定。参考:What does python print() function actually do?
2.4 默认编码方式
python 的默认编发方式为 ASCII。
如何改变python的默认编码方式?:
import sys
# sys.setdefaultencoding() does not exist, here!
reload(sys) # Reload does the trick!
sys.setdefaultencoding('UTF8')
为什么要重载sys
模块?
因为如果在编译.py
文件的之前,改变默认编码,会影响Python的编译。
当编译完,再重载sys
模块,它就是变成了第三方模块,可以随便更改,不回影响编译。setdefaultencoding()
函数才可以调用。参考:Changing default encoding of Python?
3、推荐姿势
本片文章没有列举出常见的异常,因为如果看懂了上面所有的解释。再按照下面的姿势使用,那么 python2 中的编码问题,因该就不会再困扰你了。
Unicode 三明治:尽可能的让你程序处理的文本都为 Unicode 。如下图:
了解你的字符串。你应该知道你的程序中,哪些是 unicode, 哪些是 byte,对于这些 byte 串。你应该知道,他们的编码是什么。(详情见上述小结第 4 条)
测试 Unicode 支持。使用一些奇怪的符号来测试你是否已经做到了以上几点。(测试看看你的程序是否支持中文)
参考
[python]Python2编码问题的更多相关文章
- python基础-编码_if条件判断
一.第一句Python代码 在 /home/dev/ 目录下创建 hello.py 文件,内容如下: [root@python-3 scripts]# cat hello.py #!/usr/bin/ ...
- python的编码问题
本文简单介绍了各种常用的字符编码的特点,并介绍了在python2.x中如何与编码问题作战 :) 请注意本文关于Python的内容仅适用于2.x,3.x中str和unicode有翻天覆地的变化,请查阅其 ...
- Python 字符编码 zz
http://www.cnblogs.com/huxi/archive/2010/12/05/1897271.html 1. 字符编码简介 1.1. ASCII ASCII(American Stan ...
- python 之编码问题详解
前在一个项目中遇到用post提交一个xml,xml中含有中文,对于单独的py文件,使用urllib2.urlopen完全ok,但在django中使用就一直报编码错误,然后在网上看到这篇文章不错,决定m ...
- 19.python的编码问题
在正式说明之前,先给大家一个参考资料:戳这里 文章的内容参考了这篇资料,并加以总结,为了避免我总结的不够完善,或者说出现什么错误的地方,有疑问的地方大家可以看看上面那篇文章. 以下说明是针对于pyth ...
- Python字符编码详解
1. 字符编码简介 1.1. ASCII ASCII(American Standard Code for Information Interchange),是一种单字节的编码.计算机世界里一开始只有 ...
- 【转】Python字符编码详解
转自:http://www.cnblogs.com/huxi/archive/2010/12/05/1897271.html 1. 字符编码简介 1.1. ASCII ASCII(American S ...
- python的编码问题研究------使用scrapy体验
python转码译码 *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !impo ...
- 深入理解Python字符编码--转
http://blog.51cto.com/9478652/2057896 不论你是有着多年经验的 Python 老司机还是刚入门 Python 不久,你一定遇到过UnicodeEncodeError ...
随机推荐
- Win8/8.1 下映像管理和恢复环境的配置
以前遇过不少次这种问题了,抽空记下来...... 介绍两个东西: 1. dism 部署映像服务和管理工具 主要用途是枚举.安装.卸载.配置和更新 Windows 映像中的功能和程序包. 简单地说就是有 ...
- Tasks and Back stack 详解
原文地址:http://developer.android.com/guide/components/tasks-and-back-stack.html 一个应用往往包含很多activities.每个 ...
- UIStepper 缩放:UI的使用
// 实现文件:声明在对应的.h文件.继承至UIViewControllor - (void)viewDidLoad { [super viewDidLoad]; // 按钮 self.stp = [ ...
- Quick Cocos2dx 与 DragonBones
照着官方的例子试验了一下DragonBone的使用,代码如下: local AnotherScene = class("AnotherScene", function() retu ...
- python_eval的用法
1. eval用法: 将字符串str当成有效的表达式来求值并返回计算结果. 2. eval的功能: math当成一个计算器很好用. 将字符串转换为list,tuple,dict. 3. 举例 # -* ...
- (简单) POJ 1278 Catch That Cow,回溯。
Description Farmer John has been informed of the location of a fugitive cow and wants to catch her i ...
- SQL语句详细汇总
SQL语句详细汇总 | 浏览:3061 | 更新:2013-06-10 19:50 一.基础 1.说明:创建数据库 CREATE DATABASE database-name 2.说明:删除数据库 d ...
- MySQL 启动、关闭、选择数据库等命令
一.MySQL服务的启动和停止 1.net 命令来启动或停止mysql服务 net stop mysql(mysql是指你真正装的服务,如果装的是 mysql5,必须写成 net stop mysql ...
- POJ 3458 Colour Sequence
水题. #include<cstdio> #include<cstring> #include<cmath> + ; char s[maxn], v[maxn], ...
- Unity3D ——强大的跨平台3D游戏开发工具(六)
第十一章 制作炮台的旋转 大家知道,炮台需要向四周不同的角度发射炮弹,这就需要我们将炮台设置成为会旋转的物体,接下来我们就一起制作一个会旋转的炮台. 第一步:给炮台的炮筒添加旋转函数. 给炮台的炮筒部 ...