资讯专栏INFORMATION COLUMN

聊聊Python 3 的字符串:str 和 bytes 的区别

AWang / 1927人阅读

摘要:的字符串有两种和,的字符串也有两种和。不同字符的不同表现,让的和显得扑朔迷离。在中,严格区分了和,不同类型之间操作就会抛出的异常。和之间的转换一图胜千言和的相互转换指的是具体的编码规则的名称,对于中文来说,它可以是这些值等等。

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" == 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/python
Out[3]: False

In [4]: "编程" in u"编程"
---------------------------------------------------------------------------
UnicodeDecodeError Traceback (most recent call last)
 in ()
----> 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)
 in ()
----> 1 "a" in b"a"

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]: b"Txe6x81xa4"

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

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

In [23]: c
Out[23]: b"Txd0xf4"

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)
 in ()
----> 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]: 2

In [33]: open("z.txt", "w").write(img)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
 in ()
----> 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等)

文章首发于猿人学网站:https://www.yuanrenxue.com/

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/43645.html

相关文章

  • 002_第一部分_[字典 / 列表解析 / 符串操作 / STRBYTES区别 ]

    摘要:一字典定义字典获取元素这两个的区别用在不存在的时候不会抛出设置当不存在的时候返回的内容增加和修改元素修改和增加元素的方法都是这个删除元素删除的同时返回删除的内容如果删除不存在的会报这个时候就需要给定返回值这样返回的就是不会报错误从字典中随机 一.字典: 定义字典:d = {}d = dict()d = {a:1, b:2} 1.获取元素: d[a] d.get(a) >这两个的区别,用...

    CastlePeaK 评论0 收藏0
  • Python2.x与3​​.x版本区别

    Python的3​​.0版本,常被称为Python 3000,或简称Py3k。相对于Python的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0在设计的时候没有考虑向下相容。许多针对早期Python版本设计的程式都无法在Python 3.0上正常执行。为了照顾现有程式,Python 2.6作为一个过渡版本,基本使用了Python 2.x的语法和库,同时考虑了向Python...

    neu 评论0 收藏0
  • Python 2.x 与 Python 3.x 区别

    摘要:官方也宣布在停止对的维护。并且在很多面试过程中,面试官都会问与的区别。的版本,常被称为,或简称。与部分地支持这种形式的语法。捕获异常的语法由改为。在中,表示八进制字面量的方式只有一种,就是。已经支援新的模组。 前言 如果你是刚接触 Python 的初学者,那你可能是直接学习 Python 3.x 版本。对于 Python 2.x 的版本是不会有所接触。官方也宣布在 2020 停止对 P...

    LittleLiByte 评论0 收藏0
  • 聊聊 Java8 以后各个版本新特性

    摘要:于是抽时间看了看以后各个版本的特性,做了一个总结。年和公开版本发布,取名为。此后对应版本就是,。发布,是一个重大版本更新。在此之后,就是每六个月发布一次新版本。以上和参考资料聊了一些关于的历史,下面我们看看各个版本有那些新特性。 【这是 ZY 第 11 篇原创技术文章】 某天在网上闲逛,突然看到有篇介绍 Java 11 新特性的文章,顿时心里一惊,毕竟我对于 Java 的版本认识...

    K_B_Z 评论0 收藏0
  • 详解python2python3区别

    摘要:认为有极大的优化空间,在字符串和整形操作上可以取得很好的优化结果。的和方法返回迭代器,而之前的等函数都被废弃。python有两个主要的版本,python2 和 python3 ,但是python又不同于其他语言,向下兼容,python3是不向下兼容的,但是绝大多数组件和扩展都是基于python2的,下面就来总结一下python2和python3的区别。   1.性能  Py3.0运...

    Sourcelink 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<