本人在使用Python2编写脚本工具时,观察到字符串其实有两种形式,一种是不带u
,另外一种是带u
的。仔细查询文档发现内在细节还比较多,与Python3多有差别,特此笔记。python
Python2版本与Python3版本的差别之一,即编码问题。在理解编码以前,先介绍两个概念。其中一个是字面量,另外一个是字节码。网络
在写代码时,咱们会定义字符串变量,用来表示一段文本内容。比方说 s="helloworld"
,这就是一个简单的字面量。咱们也知道,代码中的字符串变量,做为操做数可能会用于网络数据的交互,或者咱们会将这个内容存储到持久存储中。计算机的底层存储数据本质上是0和1,那么如何将这个字面量转换成字节流的数据,就是对字面量的编码。这也就是为何目前会有这么多种编码方式,比方说utf-8
,gbk
,ascii
等。工具
那么在Python2和Python3中,字面量和字节码是以不一样的类型来表示的,具体以下:编码
版本 | 字节码type | 字面量type | 默认编码方式 |
---|---|---|---|
Python2 | str | unicode | ascii |
Python3 | byte | Str | utf-8 |
这里咱们重点关注两个方面,即字节码和字面量的转换,以及默认编码方式带来的影响。code
1.字节码与字面量的转换utf-8
总的来讲,转换关系是:ci
字节码.encode(编码格式)-->字面量
unicode
字面量.decode(编码格式)-->字节码
文档
2.默认编码方式的影响字符串
在Python3中使用utf-8做为默认编码,不会通过unicode编码(utf-8是unicode一种变长类型),所以转换主要在字面量和utf-8之间。
在Python2中相对来讲会比较复杂,控制台显示的处理方式与Python3不一样。第一点,因为字面量是unicode类型,显示的时候也是一个unicode编码,没有显示字面量原本的样子,但其实他们本质是同样的。
# 这是在Python2中 >>> a = '深圳' >>> a u'\u6df1\u5733' # 对比在Python3中,其实本质是同样的 >>> '\u6df1\u5733'.encode('utf-8').decode('utf-8') >>> ‘深圳’
第二点,Python2中的unicode字面量必需要显示的带u来表示,例如a=u'深圳'
。若不带u显示表示,则是一个str字节码。
第三点,在Python3不能对字节码byte进行encode操做,而在Python2中能够对str进行encode操做。在Python2对字节码变量执行encode动做时,默认会先decode成字面量,而后再使用给定编码格式encode。这里须要注意的是decode成字面量的过程是系统自动完成的,采用的是默认的编码方式即ASCII。对于a='深圳'
这样一个含中文的字节码来讲,采用ASCII是没法decode操做的(ASCII只能decode前255个字符),所以须要修改解释器默认的编码方式。
# 含中文字符,错误展现 >>> a = '深圳' >>> a.encode('gbk') Traceback (most recent call last): File "<stdin>", line 1, in <module> UnicodeDecodeError: 'ascii' codec can't decode byte 0xe6 in position 0: ordinal not in range(128) # 纯ASCII文本,能够encode >>> a = 'zimsky' >>> a.encode('gbk') 'zimsky'
# 修改解释器默认编码方式 import sys reload(sys) sys.setdefaultencoding('utf-8')