Python3 中的 str 和 bytes

Posted 4shen0ne

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python3 中的 str 和 bytes相关的知识,希望对你有一定的参考价值。

Python3 中的 str 和 bytes

与 Python2.X 不同,Python3.X 严格区分了 str 和 bytes 两种类型。文本为 Unicode,由 str 类型表示;二进制数据则由 bytes 表示。

Python3.X 不会以任意隐式的方式混用 str 和 bytes。因此使用者不能拼接字符串和字节包,也无法在字节包里搜索字符串(反之亦然),也不能将字符串传入参数为字节包的函数(反之亦然)。

例如 Python3.X 中的socket.send()函数,如果传入未编码的字符串,会报错:

>>> client.send("test str")

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: a bytes-like object is required, not ‘str‘
    
>>> client.send(b"test str")  #将参数转换成 bytes 类型
8                           #返回发送的数据长度

编码发展的历史

在计算机历史的早期,美国为代表的英语系国家主导了整个计算机行业,26个英文字母组成了多样的英语单词、语句、文章。因此,最早的字符编码规范是ASCII码,一种8位(即1个字节)的编码规范,它可以涵盖整个英语系的编码需要。

编码是什么?编码就是把一个字符用一个二进制来表示。我们都知道,所有的东西,不管是英文、中文还是符号等等,最终存储在磁盘上都是01010101这类东西。在计算机内部,读取和存储数据归根结底,处理的都是0和1组成的比特流。问题来了,人类看不懂这些比特流,如何让这些010101对人类变得可读呢?于是出现了字符编码,它是个翻译机,在计算机内部某个地方,偷偷帮我们将比特流翻译成人类可以直接理解的文字。对于一般用户,不需要知道这个过程是什么原理,是怎么执行的。但是对于程序员却是个必须搞清楚的问题。

ASCII编码为例,它规定1个字节8个比特位代表1个字符的编码,逐个字节进行解读。例如:01000001表示大写字母A,有时我们会用65这个十进制来表示A在ASCII中的编码。8个比特位,可以无重复地最多表示2的8次方个字符;但标准的ASCII码 只有7位,码值范围是0-127,最高位为0。

后来,计算机得到普及,中文、日文、韩文等等国家的文字需要在计算机内表示,像ASCII这种单字节编码已经远远不够了,于是标准组织制定出了UNICODE(万国码),它规定任何一个字符(不管哪国的)至少以两个字节表示。其中,英文字母就是用2个字节,而汉字是3个字节。这个编码虽然很好,满足了所有人的要求,但是它不兼容ASCII,同时还占用较多的空间和内存。而在计算机世界更多的字符是英文字母,明明可以1个字节就能够表示,非要用2个,就造成了空间资源的浪费了。

于是UTF-8编码应运而生,它规定英文字母系列用1个字节表示,汉字用3个字节表示等等。因此,它兼容ASCII,可以解码早期的文档。UTF-8很快就得到了广泛的应用。

在编码的发展历程中,我国还创造了自己的编码方式,例如GBKGB2312BIG5。他们只局限于在国内使用,不被国外认可。在GBK编码中,中文汉字占2个字节。

bytes 和 str 之间的转换

test0 = ‘abc‘
test1 = b‘abc‘
print(type(test0), test0) --> <class ‘str‘> ‘abc‘
print(type(test1), test1) --> <class ‘bytes‘> b‘abc‘

test2 = bytes(test0, ‘utf-8‘)
test3 = str(test1, ‘utf-8‘)
test4 = str(test1)
print(type(test2), test2) --> <class ‘bytes‘> b‘abc‘
print(type(test3), test3) --> <class ‘str‘> ‘abc‘
print(type(test4), test4) --> <class ‘str‘> "b‘abc‘"

test5 = test0.encode() #参数可输入编码格式,默认utf-8
test6 = test1.decode()
print(type(test5), test5) --> <class ‘bytes‘> b‘abc‘
print(type(test6), test6) --> <class ‘str‘> ‘abc‘

以上是关于Python3 中的 str 和 bytes的主要内容,如果未能解决你的问题,请参考以下文章

Python 3中的str和bytes类型

python3中的bytes和string

了解python中bytes,str和unicode的区别

python3 str和bytes之间转换

python基础 python3中str和bytes

python3.5 的str类型和bytes类型的转换