Python 编码小结

Python 编码小结

1. 相关概念说明:

字符是个抽象的概念,在 Python 中字符串都是用 Unicode 表示的,那些形如 ‘abcd’ 这样常见的形式,我在这里把它称为字节串(字节序列)以示区别。当我们面对一串字节时,如果我们不知道编码方法,我们根本不知道该如何解释眼前的这些字节组成的序列。


本文中我们用  str 表示字节串,uni 表示 unicode 字符串


2. Python 内部处理字节串时的隐式转换

Python 中有好多处理字符串的函数,它们几乎都可以接受字节串和 Unicode 字符串。当传入的参数是字节串时,Python 会先用默认的 ASCII 编码将这串字节转换成对应的 Unicode 字符串,然后再使用相应的函数进行处理,因此当字节序列中,出现码值大于 127的字节时,解码就会出错:

>>> s.find('Was\x9f')                   
Traceback (most recent call last):
    ...
UnicodeDecodeError: 'ascii' codec can't decode byte 0x9f in position 3: ordinal not in range(128)

>>> s.find(u'Was\x9f')
-1

那么如何判断一个字符串到底是字节序列还是 unicode 呢?从外观上可以这样判断,凡是字符串引号前面没有加 ‘u’的都是字节串,加了 ‘u’的是 Unicode 字符串。

In [1]: t = '中文'

In [2]: type(t)
Out[2]: str

In [3]: t = u'中文'

In [4]: type(t)
Out[4]: unicode


用代码可以这样判断:

In [5]: def is_unicode(string):
   ...:         return isinstance(string, unicode)
   ...:

In [6]: is_unicode('中文')
Out[6]: False

In [7]: is_unicode(u'中文')
Out[7]: True

3. 一般处理流程

在 Python 中字符串都是用 Unicode 表示的,所以当我们要对这些字符串进行存储或者传输时,就需要对这些字符进行适当的编码,使这些字符串转换成适合存储和传输的字节序列。因此典型的处理流程是这样的:

文件读取或键盘输入的字节序列 ---(解码)---- 适合Python 程序使用的 Unicode 字符串 -----(编码)---- 适合存储或传输的字节序列形式

用符号可以这样表示:

str -> decode('the_coding_of_str') -> unicode # 字节串解码得到 Unicode

unicode -> encode('the_coding_you_want') -> str # Unicode 编码得到字节串


不同编码之间的转换,需要使用 Unicode 字符串作为转换的中间格式, 转换流程如下:

str.decode('the_coding_of_str').encode('the_prefered_coding_of_str')


encode 和 decode 函数使用须知,字节串调用encode 或者 Unicode 调用decode都会引起隐式转换

str.encode('xxx')  -----> str.decode('ascii').encode('xxx')

uni.decode('xxx') ------> uni.encode('ascii').decode('xxx')

这样,只要字节串中码值大于 127 或者 Unicode 中字符的代码点的值大于 127 就会抛出,UnicodeDecodeError 或 UnicodeEncodeError。所以避免错误的一个原则是:字节串尽量不使用 encode函数,unicode 尽量不要使用 decode 函数



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值