Published on

Python 字符串与 Unicode

Authors

Python 字符串与 Unicode

为什么会存在编码这个问题

首先编码的目的是为了解决字符集在计算机底层的存储,以及网络上的传输问题。我们都知道计算机只认识 01 , 但是这些数字对我们人类是没有任何意义的。如果我们可以直接阅读 01 代码,那么就不存在编码的问题了。

在用Python处理中文的时候,经常会遇到一些关于编码方面的问题,以前都是遇到问题的时候直接去 Google ,如果不把这个问题彻底搞清楚,这个问题会一直困扰我的。今天拿出一点时间来,打算彻底研究一下这个问题。

Python2 到 Python3 编码上的变化

python2python3 的变化主要有三类:

  • 语法的变化
  • 函数的变化
  • 编码的变化

其中编码的变化是最难处理的变化,这里主要谈一下 python2python3 编码到底是如何变化的。

Python2 中关于编码问题的处理

Python 2 中的默认编码

sys.getdefaultencoding() 可以得到当前 Python 环境的默认编码,Python 2 中为ascii。str与unicode两种字符类型中转化时,如果没有明确指定编码方式,就会用这个默认编码。

str 和 unicode

Python中有两种字符串类型,分别是 strunicode ,它们都由抽象类型 basestring 派生而来。str 字符串其实是字节组成的序列,unicode 字符串则表示为 unicode 类型的实例。因为 Python2 还是默认使用 ascii ,所以,在处理中文的时候,如果不指定编码,会遇到很多莫名其妙的问题。

UnicodeEncodeError: ‘ascii’ codec can’t encode characters in position 51-52: ordinal not in range(128)

还记得当时使用 Python2 的时候回出现下面这种问题:

SyntaxError: Non-ASCII character '\xe4' in file str.py on line 2, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details

解决的办法是在模块文件的首部添加如下声明:

** # -- encoding: utf-8 -- **

Python3 对编码问题的改善

关于 Unicode 编码

简单来讲,Unicode 属于万国码,是为了解决跨语言,跨平台处理文本的需求。Unicode 只是规定了如何编码,但是并没有规定如何保存和传输这个编码。所以 Unicode 编码有不同的实现方式,例如: UTF-8UTF-16 等。

Python3 中如何编码

Python3 中解析器会默认采用 UTF-8 解析源程序。并且,字符串也是以 Unicode 编码的,如下所示:

>>> print('包含中文的str')
包含中文的str

对于单个字符的编码,Python 提供了 ord() 函数获取字符的整数表示,**chr()**函数把编码转换为对应的字符:

>>> ord('A')
65
>>> ord('中')
20013
>>> chr(66)
'B'
>>> chr(25991)
'文'

关于 Unicode 和 str 的关系

由于Python的字符串类型是 str,在内存中以 Unicode 表示,一个字符对应若干个字节。如果要在网络上传输,或者保存到磁盘上,就需要把 str 变为以字节为单位的 bytes