二进制序列类型——bytes()、bytearray()
本文作者:余术玲
文字编辑:孙晓玲
导读
今天要给大家介绍一种新的数据类型:二进制序列。在Python3以后,字符串和bytes类型彻底分开了,从此,字符串主要是给人看的,bytes类型是给计算机看的。Python3最重要的新特性大概要算是对文本和二进制数据作了更为清晰的区分。文本总是Unicode,由str类型表示,二进制数据则由bytes类型表示。Python3不会以任意隐式的方式混用str和bytes,正是这使得两者的区分特别清晰。你不能拼接字符串和字节包,也无法在字节包里搜索字符串(反之亦然),也不能将字符串传入参数为字节包的函数(反之亦然),小编今天将详细介绍二进制序列类型。
bytes()
(一)bytes对象
字符串(string)是以字符为单位进行处理的,由一系列不可改变的Unicode字符组成。bytes是以字节为单位处理的(字节是计算机信息技术用于计量存储容量的一种计量单位,通常情况下,一字节是八位)。
bytes对象是以二进制字节序列的形式记录的对象,由一系列不可改变的介于0-255之间的数字构成,至于该对象到底表示什么(比如到底是什么字符)则由相应的编码方式所决定。
Python3中,bytes对象可用于在网络上传输数据,也可用于存储各种二进制格式的文件,比如图片、音乐等文件。bytes数据类型在所有的操作和使用甚至内置方法上和字符串数据类型基本一样,也是不可变的序列对象。
这里总结一下Python中的bytes和str类型,以及它们和编码解码到底是什么关系。bytes对象是二进制,主要是给在计算机看的,string就是我们看到的内容,例如’abc’,主要是给人看的。中间有个桥梁就是编码规则,目前有很多种编码规则(UTF-8、UTF-16、GBK等)。string经过编码(encode),转化成二进制对象给计算机识别,也就是bytes类型。bytes经过反编码(decode),转化成string。关于这编码与解码方面的知识,读者可以参考之前的文章《encode 和decode——带你探索编码与解码的世界》。
(二)bytes定义
首先,表示bytes字面值的语法与字符串字面值的大致相同,只是添加了一个b前缀:
单引号: b' '
双引号: b" "
三重引号: b''' ''', b""" """
bytes对象可以通过以下几种方式来创建:
1.使用b前缀定义:
1.1直接输入字面值
bytes字面值中只允许ASCII字符(无论源代码声明的编码为何)。例如在下例中,b'12bfg'不会报错,但b'中国'则会报错,因为ASCII中没有中文编码:
In [2]: a=b'12bfg'
...: a
Out[2]: b'12bfg'
In [3]: b=b'中国'
...: b
File "<ipython-input-3-e7b1ac6d6f71>", line 1
b=b'中国'
^
SyntaxError: bytes can only contain ASCII literal characters.
1.2 使用十六进制表示
In [4]: c=b'\x41\x61'
...: c
Out[4]: b'Aa'
2.内置函数bytes()
使用内置函数bytes()可以定义一个空的bytes对象:
In [5]: d=bytes()
...: d
Out[5]: b''
3.bytes(int)
可以直接定义字节的个数,就是创造了几个空字节,但是每个字节里面是空的。例如:
In [6]: e=bytes(4)
...: e
Out[6]: b'\x00\x00\x00\x00'
bytes(4)表示定义一个长度为4的字节组成的数组,被\x00填充,这是ASCII,代表空字符,不是阿拉伯数字0(阿拉伯数字0是十进制48,十六进制30)。
4.bytes(iteratable)
创造可迭代对象的元素个数相等的字节,然后把每个元素填充进去作为值,注意iteratable必须是整型int的可迭代对象,且int取值范围必须是0-255。例如,传入range(14):
In [5]: g=bytes(range(14))
...: g
Out[5]: b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r'
依照ASCII表,9对应\t,10对应\n,13对应\r。这就是用ASCII表来解码的字节。
又例如:
In [1]: f=bytes([67,68,69])
...: f
Out[1]: b'CDE'
5.使用bytes来构造bytes对象
可以从一个字节序列复制出一个新的不可变的bytes对象。
In [4]: h=bytes(b'123')
...: h
Out[4]: b'123'
6.使用str构造bytes序列
可以将string编码成bytes,需要指定编码。
In [6]: i=bytes("1234",encoding="utf-8") #使用utf-8进行编码
...: i
Out[6]: b'1234'
(三)bytes操作
bytes类型和字符串类型类似,都是不可修改的类型,所以所谓的修改都是创造一个新的bytes和str。bytes和str方法类似,只不过bytes的方法,输入是bytes,输出是bytes。下面介绍几个常用的bytes方法。
1.bytes.find(sub[,start[, end]]) 用来查找某个字节的索引号
In [1]: b'beautiful'.find(b'u')
Out[1]: 3
2.bytes.replace(old, new[, count])用来替换字节
In [3]: b'beautiful'.replace(b'u',b'a')
Out[3]: b'beaatifal'
3.bytes.fromhex(‘hexstr’)用一串由十六进制数字组成的字符串来表示字节,字符串必须由表示每个字节的两个十六进制数码构成,其中的ASCII空白符会被忽略。
In [4]: bytes.fromhex('4d 79 20 44 69 63 6b')
Out[4]: b'My Dick'
注意在括号内,空格是无效的,相当于没输入,所以要打出空格就要打ASCII编码表里空格对应的编码,也就是20。
bytearray()
bytearray 对象是bytes对象的可变对应物,bytearray为可变的字节序列,bytearray基本方法与bytes类型部分相同,但是bytearray为可变字节序列,所以可以进行可变序列的增删改操作。
(一)bytearray()定义
In [1]: ba=bytearray()
...: ba
Out[1]: bytearray(b'') #定义一个空bytearray
In [3]: ba4=bytearray(4)
...: ba4
Out[3]: bytearray(b'\x00\x00\x00\x00') #定义指定长度的字节数组bytearray,默认以0填充
In [4]: b14=bytearray((1,2,3,4))
...: b14
Out[4]: bytearray(b'\x01\x02\x03\x04') #定义指定内容的bytearray,bytearray(整型可迭代对象),int整型组成的可迭代对象里的元素,依次取出,放在字节数组的字节中。
In [6]:b15=bytearray("ABCD",encoding="utf-8")
...: b15
Out[6]: bytearray(b'ABCD') #使用utf-8进行编码,利用str构造bytearray可变字节序列
In [7]: b16=bytearray(b'abc')
...: b16
Out[7]: bytearray(b'abc') #从一个字节序列复制出来一个新的可变的bytearray对象
(二)bytearray()操作
bytearray()方法除了有bytes()方法类似的查找某个字节的索引号,替换字节等外,还有增删改的方法。
1.append(int)在bytearray对象尾部追加一个元素
In [10]: b=bytearray()
...: b.append(98)
...: b
Out[10]: bytearray(b'b')
2.insert(index,int)在指定位置插入元素
In [11]: b.insert(1,100)
...: b
Out[11]: bytearray(b'bd')
3.extend(iyterable_of_ints)将一个可迭代的整数集合追加到当前的bytearray
In [15]: b.extend([70,71,72])
...: b
Out[15]: bytearray(b'bdFGH')
4.remove(value)找到第一个value移除,找不到就报ValueError异常
In [16]: b.remove(72)
...: b
Out[16]: bytearray(b'bdFG')
5.pop(index)从指定索引上移除元素,默认从尾部移除
In [19]: b.pop(0)
...: b
Out[19]: bytearray(b'dFG')
6.clear()用来清空bytearray
In [20]: b.clear()
...: b
Out[20]: bytearray(b'')
以上就是为大家介绍的二进制序列类型,总结一下:字符串是字符组成的有序序列,bytes是字节组成的有序的不可变的序列,bytearray是字节组成的有序的可变序列。在实际应用中,有的网站需要传入二进制参数,此时需要将string转换成bytes,否则就不能得到我们想要的信息,如果大家在爬虫的时候有遇到无法爬取的情况,可以检查一下是否传入的汉字参数需要变成编码形式~
关于我们
微信公众号“Stata and Python数据分析”分享实用的stata、python等软件的数据处理知识,欢迎转载、打赏。我们是由李春涛教授领导下的研究生及本科生组成的大数据处理和分析团队。
1)必须原创,禁止抄袭;
2)必须准确,详细,有例子,有截图;
注意事项:
1)所有投稿都会经过本公众号运营团队成员的审核,审核通过才可录用,一经录用,会在该推文里为作者署名,并有赏金分成。
2)邮件请注明投稿,邮件名称为“投稿+推文名称”。
3)应广大读者要求,现开通有偿问答服务,如果大家遇到有关数据处理、分析等问题,可以在公众号中提出,只需支付少量赏金,我们会在后期的推文里给予解答。