pythonunicode和str的区别_Python:了解bytes、str 与 unicode 的区别

[广告:最高 ¥2000 红包]阿里云服务器、主机等产品通用,可叠加官网常规优惠使用 | 限时领取

在Python3中,有两种类型的字符代表序列:bytes(字节)和 str(字符串)。字节的实例包含8个原生的比特值,而字符串的实例则是用Unicode字符来堆砌的。

在Python2中,有两种类型的字符代表序列:str(字符串) 和 unicode(Unicode字符)。与Python3相反,字符串实例代表着原生的8比特值序列,而unicode则由Unicode字符堆砌而成。

有许多方法来表示Unicode字符的二进制数据(原生的8比特值 序列)。最常用的编码方式为UTF-8编码。还有一点很重要,那就是Python3中的字符串实例和Python2中的unicode实例并没有相关联的二进制编码。所以要想将Unicode字符转换成二进制数据,就必须使用encode方法,反过来,要想把二进制数据转换成Unicode字符,就必须使用decode方法。

当你开始写Python程序的时候,在接口的最开始位置声明对Unicode的编码解码的细节很重要。在你的代码中,最核心的部分应使用Unicode字符类型(Python3中使用str,Python2中使用unicode)并且不应该考虑关于字符编码的任何其他方式。本文允许你使用自己喜欢的可替代性的文本编码方式(如Latin-1,Shift JIS, Big5),但是应该对你的文本输出编码严格的限定一下(理想的方式是使用UTF-8编码)。

由于字符类型的不同,导致了Python代码中出现了两种常见的情形的发生。

你想操作UTF-8(或者其他的编码方式)编码的8比特值 序列。

你想操作没有特定编码的Unicode字符。 所以你通常会需要两个工具函数来对这两种情况的字符进行转换,以此来确保输入值符合代码所预期的字符类型。

在Python3中

你将需要一个方法,接收str或者bytes,总是来返回str类型的数据。如下:

def to_str(bytes_or_str):

if isinstance(bytes_or_str,bytes):

value = bytes_or_str.encode('utf-8')

else:

value = bytes_or_str

# str类型的数据

return value

同理,我们需要另一个方法,来接收str 或 bytes ,总是来返回bytes类型的数据。

def to_bytes(bytes_or_str):

if isinstance(bytes_or_str,str):

value = bytes_or_str.encode('utf-8')

else:

value = bytes_or_str

# 字节类型的数据

return value

在Python2中

需要一个方法,来接收str或者unicode类型的数据,总是来返回unicode类型的数据。

def to_unicode(unicode_or_str):

if isinstance(unicode_or_str,str):

value = unicode_or_str.encode('utf-8')

else:

value = unicode_or_str

# unicode类型的数据

return value

同理,需要一个接收str或者unicode类型的数据,总是来返回str类型的数据。

def to_str(unicode_or_str):

if isinstance(unicode_or_str,unicode):

value = unicode_or_str.encode('utf-8')

else:

value = unicode_or_str

# str类型的数据

return value

两大陷阱

在Python中处理原生的8比特值 序列以及Unicode字符的时候,有两大陷阱。

一个是在Python2中,当一个str数据仅仅包含7比特的ASCII码字符的时候,unicode和str实例看起来是一致的。

可以使用‘+’运算符和合并str和unicode。

可以使用等价或者不等价运算符来比较str和unicode实例。

可以使用unicode来代换 像‘%s’这种字符串中的格式化占位符。

以上行为意味着,如果你的代码中仅仅处理原生的7比特序列,那么便可以不必在意是str类型的数据还是unicode类型的数据了。在Python3中,bytes和str实例是不可能等价的,即使是空的字符串也不可能等价。所以你必须谨慎地对正在处理的代码进行字符类别的区分处理。

另一个是在Python3中,涉及到文件处理的操作(使用内置的open函数)会默认的以UTF-8进行编码。而在Python2中默认采用二进制形式来编码。这也是导致意外事故发生的根源,特别是对于那些更习惯于使用Python2的程序员而言。

比方说,你想将几个随机的二进制数据写入到一个文件中。在Python2中,下面的这段代码可以正常的工作,但是在Python3中却会报错并退出。详细信息如下。

def open('/tmp/random.bin','w') as f:

f.write(os.urandom(10))

>>>

TypeError: must be str,not bytes

导致这个异常发生的原因是在Python3中对于open函数又新增了一个名为encoding的参数。此参数默认为UTF-8。这使得其对于文件的读写操作预期的源为包含了Unicode字符串的str实例,而不是包含了二进制数据的字节文件。

为了使得上面的函数正常的工作,我们必须指明被操作的数据是以‘wb’模式打开,而不是简单的‘w’模式。这里,作者介绍了一个在Python2和Python3 中都通用的方法,详细如下。

with open('/tmp/random.bin','wb) as f:

f.write(os.urandom(10))

好了,写文件的问题算是解决了,但是不要忘了还有读文件的问题哦。同样的我们也只需要改变一下读文件的模式即可。即‘r’换成‘rb’。

要点:

在Python3中,字节包含的是8个比特值的序列,str是包含Unicode的字符的串。字节和字符串实例不能同时出现在操作符‘>’ 或者 ‘+’中。

在Python2中,str是包含8个比特值的序列,unicode是包含Unicode字符的串,二者可以同时出现在只包含7个比特的ASCII码的运算中。

使用工具函数来确保程序输入的数据时程序预期的类型。

总是使用‘wb’和‘rb’模式来写文件和读文件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值