当前位置: 移动技术网 > IT编程>脚本编程>Python > 浅析Python 3 字符串中的 STR 和 Bytes 有什么区别

浅析Python 3 字符串中的 STR 和 Bytes 有什么区别

2018年11月09日  | 移动技术网IT编程  | 我要评论

多肉花卉,cscdkey序列号1.6,惠众生商城

python2的字符串有两种:str和unicode,python3的字符串也有两种:str和bytes。python2的str相当于python3的bytes,而unicode相当于python3的bytes。

python2里面的str和unicode是可以混用的,在都是英文字母的时候str和unicode没有区别。

而python3严格区分文本(str)和二进制数据(bytes),文本总是unicode,用str类型,二进制数据则用bytes类型表示,这样严格的限制也让我们对如何使用它们有了清晰的认识,这是很棒的。

python2 和 python3 的区别

通过以下代码我们认识以下python2和python3的字符串混用情况:

# python2中:in [1]: 'a' == u'a'out[1]: true

in [2]: 'a' in u'a'out[2]: true

in [3]: '编程' == u'编程'/usr/local/bin/ipython:1: unicodewarning: unicode equal comparison failed to convert both arguments to unicode - interpreting them as being unequal#!/usr/bin/pythonout[3]: false

in [4]: '编程' in u'编程'---------------------------------------------------------------------------unicodedecodeerror traceback (most recent call last)
<ipython-input-4-7b677a923254> in <module>()
----> 1 '编程' in u'编程'

unicodedecodeerror: 'ascii' codec can't decode byte 0xe7 in position 0: ordinal not in range(128)

# python3中:

in [1]: 'a' == b'a'out[1]: false

in [2]: 'a' in b'a'---------------------------------------------------------------------------typeerror traceback (most recent call last)
<ipython-input-10-ca907fd8856f> in <module>()
----> 1 'a' in b'a'

typeerror: a bytes-like object is required, not 'str'

以上代码可以看到,python2中str和unicode在都是ascii码时混用没区别,因为unicode的ascii区域的值跟str的ascii是一样的;而对应非ascii区域(比如中文),二者又不一样了。

可以看到python2抛出了unicode decode error的异常,相信这也是很多人处理文本时遇到过的错误;‘编程'在str类型时长度是6,而在unicode时是2。不同字符的不同表现,让python2的str和unicode显得扑朔迷离。

在python3中,严格区分了str和bytes,不同类型之间操作就会抛出type error的异常。

上面用示例阐述了python2和python3中字符串的不同,下面主要讲python3中的字符串。

str和bytes之间的转换

一图胜千言:

str和bytes的相互转换

str.encode(‘encoding') -> bytes
bytes.decode(‘encoding') -> str

encoding指的是具体的编码规则的名称,对于中文来说,它可以是这些值: ‘utf-8', ‘gb2312', ‘gbk', ‘big5' 等等。

不知道你有没有注意到上图中str矩形要比bytes矩形短,表示同样的内容,str的长度要小于或等于bytes的长度,你可以考虑一下原因(参考unicode、utf-8的编码规则)。

下面看看具体代码理解一下str和bytes的相互转换:

in [16]: a = 't恤'in [17]: a
out[17]: 't恤'in [18]: len(a)
out[18]: 2in [19]: b = a.encode('utf8')

in [20]: b
out[20]: b't\xe6\x81\xa4'in [21]: a == b
out[21]: falsein [22]: c = a.encode('gbk')

in [23]: c
out[23]: b't\xd0\xf4'in [24]: b == c
out[24]: falsein [25]: a == c
out[25]: false

上面str和bytes之间的转换是针对文本内容的,要是其它二进制内容(比如,图片)时,bytes就不能decode成str了,看以下代码的异常:

in [29]: img = open('str-bytes.jpg', 'rb').read()

in [30]: type(img)
out[30]: bytes

in [31]: img.decode('utf8')
---------------------------------------------------------------------------
unicodedecodeerror traceback (most recent call last)
<ipython-input-31-c9e28f45be95> in <module>()----> 1 img.decode('utf8')unicodedecodeerror: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte

因为图片中的二进制数据不符合文本数据的utf-8编码规则。

上面获得图片数据时,我们用到了open()来读取文件,文件存储的无非是文本和二进制这两种格式,读写文件时也有分清楚编码:

in [32]: open('z.txt', 'w').write('t恤')
out[32]: 2in [33]: open('z.txt', 'w').write(img)
---------------------------------------------------------------------------
typeerror traceback (most recent call last)
<ipython-input-33-4a88980b3a54> in <module>()
----> 1 open('z.txt', 'w').write(img)

typeerror: write() argument must be str, not bytes

in [34]: open('z.txt', 'wb').write(img)
out[34]: 12147

读写二进制数据(如图片)时,要加'rb'参数,b代码binary(二进制)。读写文本数据时,一般加'b',open()会自动转换bytes到str。

总结一下

python3里面的str是在内存中对文本数据进行使用的,bytes是对二进制数据使用的。

str可以encode为bytes,但是bytes不一定可以decode为str。实际上bytes.decode(‘latin1')可以称为str,也就是说decode使用的编码决定了decode()的成败,同样的,utf-8编码的bytes字符串用gbk去decode()也会出错。

bytes一般来自网络读取的数据、从二进制文件(图片等)读取的数据、以二进制模式读取的文本文件(.txt, .html, .py, .cpp等)。

总结

以上所述是小编给大家介绍的python 3 字符串中的 str 和 bytes 有什么区别,希望对大家有所帮助

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网