
Python 3 有两种表示字符序列的类型:bytes和str。前者的实例包含原始的8位值;后者的实例包含Unicode字符。
Python 2也有两种表示字符类型,str和unicode。与python 3 不同的是,str的实例包含原始的8位值^8位值;而unicode的实例,则包含Unicode字符。
把Unicdde字符表示为二进制数据(也就是原始的8位值)有许多的方法。最常见的为UTF-8。但是,python 3的str实例和python 2的unicode实例都没有和特定的二进制编码形式相关联。将Unicode字符转换为二进制数据,使用encode。反过来,使用decode方法。
编写python,一定要把编码和解码操作放在界面的最外围来做,程序的核心部分应使用Unicode字符类型(python 3中str,python 2中unicode),而且不要对字符编码做任何假设。此方法有两个好处:
令程序接受多种类型的文本编码
保证输出的文本信息只采用一种编码形式(最好是UTF-8)
由于字符有别,所以python代码中经常两种的使用情景:
- [ ] 开发者需要原始8位值,这些8位值表示以UTF-8格式(other)来编码的字符。
- [ ] 开发者需要操作没有特定编写形式的Unicode字符。
所以,需要编写两个helper函数,在两种情况里转换,使得转换后的输入数据可符合预期。
在python 3中,需要编写接受str或bytes,并总是返回str的方法:
1 |
def (bytes_or_str): |
另外,还需要编写接受str或bytes,并总是返回bytes的办法:
1 |
def to_bytes(bytes_or_str): |
在python 2中,需要编写接受str或unicode,并总是返回unicode的方法:
1 |
# python 2 |
另外,需要接受str或unicode,并总是发返回str的方法:
1 |
# python |
在python中使用8位值与Unicode字符时,要注意:
第一个问题可能会出现在python 2里面,如果str只包含7位ASCII字符,那么unicode和str实例似乎就成了同一种类型。
- [ ] 可以用+操作符这种str和unicode链接起来。
- [ ] 可以用等价与不等价操作符,在这种str实例与unicode实例之间进行比较。
- [ ] 在格式字符串中,可以用’%s’等形式来代表unicode实例。
这些行为意味着,在只处理7位ASCII的情境下,如果某函数接受str,那么可以给它传入unicode;如果某函数接受unicode,那么也可以给它传入str。而在python 3中,bytes与str实例则结对不会等价,即使空字符串也不行。所以,在传入字符串列的时候必须留意其类型。
第二个问题可能会出现在python 3中,如果通过内置的open函数获取了文件句柄 (file handle) ,那么注意,该句柄默认采用UTF-8编码格式来操作文件。而在python 2中,文件操作的默认编码格式则是二进制形式。这可能会导致程序出现奇怪的错误。
例如,现在向文件中随意写入一些二进制数据。下面这种用法在python 2中可以正常运作,not pytnon 3.
1 |
with open ('/tem/random.bin','w') as f |
原因在于:python 3给open函数添加了名为enocdeing的新参数,新参数默认值为’utf-8’.这样在文件句柄上进行read和write操作,系统要求开发者必须传入包含Unicoe字符的str实例,而不接受包含二进制数据的bytes实例。
用二进制写入模式(’wb’)来开启代操作的文件。同时适配与python 2和python 3 。




近期评论