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的字符串混用情况:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
# 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的相互转换
1
2
|
str .encode(‘encoding') - > bytes bytes.decode(‘encoding') - > str |
Encoding指的是具体的编码规则的名称,对于中文来说,它可以是这些值: ‘utf-8', ‘gb2312', ‘gbk', ‘big5' 等等。
不知道你有没有注意到上图中str矩形要比Bytes矩形短,表示同样的内容,str的长度要小于或等于Bytes的长度,你可以考虑一下原因(参考Unicode、UTF-8的编码规则)。
下面看看具体代码理解一下str和Bytes的相互转换:
1
2
3
4
5
6
7
8
9
10
11
12
|
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了,看以下代码的异常:
1
2
3
4
5
6
7
8
9
|
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()来读取文件,文件存储的无非是文本和二进制这两种格式,读写文件时也有分清楚编码:
1
2
3
4
5
6
7
8
9
10
11
|
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 有什么区别,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!