首页 > 编程语言 > 详细

Python 3 中字符串和 bytes 的区别

时间:2019-01-09 23:54:22      阅读:271      评论:0      收藏:0      [点我收藏+]

来自猿人学Python教程的学习笔记。 https://www.yuanrenxue.com/

在Python中字符串和unicode真是傻傻分不清楚,在没搞懂两个区别时,你会发现程序报的错怎么改都是再报错,让你烦躁。

学习Python的时候,又重温了这部分内容,写了这个学习笔记。

技术分享图片

 

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

Python2里面的str和unicode是可以混用的,在都是英文字母的时候str和unicode没有区别。而Python3 严格区分文本(str)和二进制数据(bytes),文本总是unicode,用str类型,二进制数据则用bytes类型表示,这样严格的限制也让我们对如何使用它们有了清晰的认识,这是很棒的。

Python2 和 Python3 的区别

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

# Python2中:

In [1]: a == ua
Out[1]: True

In [2]: a in ua
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/python
Out[3]: False

In [4]: 编程 in u编程
---------------------------------------------------------------------------
UnicodeDecodeError Traceback (most recent call last)
<ipython-input-4-7b677a923254> in <module>()
----> 1 编程 in u编程

UnicodeDecodeError: ascii codec cant decode byte 0xe7 in position 0: ordinal not in range(128)

# Python3中:

In [1]: a == ba
Out[1]: False

In [2]: a in ba
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-10-ca907fd8856f> in <module>()
----> 1 a in ba

TypeError: a bytes-like object is required, not str

 

以上代码可以看到,Python2中str和unicode的在都是ascii码时混用没区别,因为unicode的ascii区域的值跟str的ascii是一样的;而对应非ascii区域(比如中文),二者又不一样了,可以看到Python2抛出了UnicodeDecodeError的异常,相信这也是很多人处理文本时遇到过的错误;‘编程’在str类型时长度是6,而在unicode时是2。不同字符的不同表现,让Python2的str和unicode显得扑朔迷离。

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

上面用示例阐述了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]: 2

In [19]: b = a.encode(utf8)

In [20]: b
Out[20]: bT\xe6\x81\xa4

In [21]: a == b
Out[21]: False

In [22]: c = a.encode(gbk)

In [23]: c
Out[23]: bT\xd0\xf4

In [24]: b == c
Out[24]: False

In [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 cant decode byte 0xff in position 0: invalid start byte

 

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

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

In [32]: open(z.txt, w).write(T恤)
Out[32]: 2

In [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。

 

Python 3 中字符串和 bytes 的区别

原文:https://www.cnblogs.com/amiza/p/10247538.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!