概述
最近工作中的项目同时使用到了 Python2 和 Python3 ,遇到了文本和字节的 tricks,自己之前对这方面不太了解,学习并总结一下。
编码介绍
Unicode 标准
Unicode 是用于表示文本以供计算机进行处理的通用字符编码标准。Unicode 标准提供了一种对多语种纯文本进行一致编码的方法,便于国际文本文件的交换。
字符 的最佳定义是 Unicode 字符 。Unicode 只是一个符号集,它只规定了符号的二进制代码,并没有规定这个二进制代码应该如何存储。
UTF-8
UTF-8 字符编码是 Unicode 的实现方式之一。
UTF-8 是一种变长的编码方式,它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。
Python 中的文本和字节
Python3 中从 str 对象中获取的元素就是 Unicode 字符,可以通过 编码 (encode) 将 文本 转化为 字节。
然而 Python2 中从 str 对象中获取的元素是字节序列,只有通过 解码 (decode) 才能将 字节 转化为 文本 。
下面使用两个版本的 Python 对字符串进行操作以作解释:
1 | # py3 |
1 | # py2 |
从上面的程序可以总结出 Python2 和 Python3 对于字符串处理上的区别:
Python2 | Python3 | |
---|---|---|
Unicode strings | unicode | str |
Bytes strings | str | bytes |
Python 中的 u
, b
, r
Python 的字符串有时候前面会加一个 u
,r
或者 b
,其含义如下:
u
:表示字符串中的元素是 Unicode 字符。结合上面表格的结论,可以认为:在 Python3 中,字符串前面是否加 u
的效果是一致的。在 Python2 中,字符串前面加 u
表示其中的元素是 Unicode 字符,不加 u
表示 bytes。
b
:表示字符串中的元素是 Bytes。同结合上面表格的结论,可以认为:在 Python2 中,字符串前面是否加 b
的效果是一致的。在 Python3 中,字符串前面加 b
表示其中的元素是 bytes,不加 b
表示 Unicode 字符。
r
:表示字符串是 原始字符串(raw string) ,里面的字符都是 raw string literals ,与 Unicode 和 Bytes 无关,因此 Python2 和 Python3 中含义是一致的。它的作用是使解释器不会对诸如 \n
, \t
等转义字符进行转义:
1 | # py3 |
Python2 和 Python3 在字符串处理方面的兼容
既然 Python2 和 Python3 在字符串的处理方面有所不同,但是实际工作中却需要写出兼容两种版本的代码,那么应该如何处理呢?
我的做法是使用 __future__
模块:
1 | from __future__ import unicode_literals |
该模块的作用是将 Python2 的字符串字面量的类型变为文本,而不是字节,因此与 Python3 是一样的。
举个栗子:
1 | # py2 |
总结
目前 Python2 与 Python3 是并存的,因此在编写代码过程中需要注意其中的差异和兼容性,不然就要出锅了hhh(虽然 Python2 在 2020 年 1 月就要停止维护了)。