8.二进制序列类型——bytes,bytearray,memoryview
bytes和bytearray是核心内置类型中用于操作二进制数据的存在。而memoryview是用来支持它们的存在,该类型使用缓冲器协议访问其他二进制对象的内存,从而跳过复制操作,获取数据。附带提及一下,array模块支持基本数据类型(比如32位整型和IEEE754定义的双精度浮点数)的高效存储。
8.1字节(bytes)对象
字节对象是由一系列单个字节构成的不可变序列。由于许多主流的二进制协议都是基于ASCII文本编码,因此字节对象提供了许多方法专门处理基于ASCII编码的数据,也提供了一些将二进制与字符串关联的方法。
class bytes([source[, encoding[, errors]]])
首先,字节文字的语法与字符串文字的语法基本相同,只是添加了b前缀,例如:
1.单引号:b‘ stillallows embedded “double” quotes’ (单引号中允许嵌入双引号)
2.双引号:b” still allows embedded ‘single’ quotes” (双引号中允许嵌入单引号)
3.三引号:b‘’’ 3 single quotes’’’,b”””3 double qutotes”””
在字节文字中只有ASCII字符被允许这样操作。任何值超过127的二进制值必须经由适当的转义序列转化为字节文字。与字符串文字一样,字节文字也可以使用r前缀来禁用转义序列的对其的操作。尽管字节文字和字节表达式是基于ASCII文本,但字节对象的实际行为却与不可变整型序列类似,并且,序列中的每个值必须遵循诸如0<=x<256的限制(超出本限制会产生ValueError)。
除了文字形式外,字节对象也可以通过以下方法创建:
1. 为一个空字节对象指定长度,如:bytes(10)
2. 从一个整型迭代器创建,如:bytes(range(20))
3. 从寄存器协议中赋值一个已存在的二进制数据,如:bytes(obj)
classmethodfromhex(string)
该字节类方法返回一个字节对象,数据由给出的obj字符串对象编码而来。该字符串要求每字节数据中包含两个十六进制数,此外其中的ASCII空格会被忽略。
hex()
返回一个字符串对象,要求实例中每字节包含两个十六进制数。
8.2 字节数组(bytearray)对象
字节数组对象是字节对象的可变副本。
class bytearray([source[, encoding[, errors]]])
由于没有专用语法用于bytearray对象,因此需要通过调用构造器来对其进行构造:
1. 创建一个空的实例,例如:bytearrary()
2. 创建一个零填充的符合给定长度要求的实例,例如:bytearrary(10)
3. 从整数迭代器中构造,例如:bytearrary(range(20))
4. 通过缓冲区协议复制已存在的二进制数据,例如:bytearray(b’Hi!’)
字节数组对象是可变对象,它支持可变序列操作以及字节对象的共有操作和Bytes and Bytearrary Operations中的字节数组操作。
由于两个十六进制数字精确对应一个字节,因此十六进制数字被广泛应用于标准描述二进制数据。相应的,在这种格式下,字节数据类型有自己额外的类方法用于读取数据:
classmethodfromhex(string)
该类方法返回一个字节数组对象,数据由string参数携带的数据编码而来。string对应的字符串应当每字节包含两个十六进制数,空格不计入数据中。
此外,系统也提供了一个反函数,将实例中的字节数据转化为两个十六进制数:
hex()
将实例中每个字节转化为两个十六进制数
尽管字节数组对象是整数序列,但是要注意的是,对于字节数组对象b,b[0]是一个整型数,但b[0:1]却是一个长度为1的字节数组对象。
8.3字节和字节数组操作
所有的字节和字节数组对象都支持通用序列操作。并且,它们的交互操作不仅支持相同的数据类型,也支持任何类似于字节的对象。由于这样的高灵活性,他们可以在操作中自由混合而不会造成错误。然而需要注意的是,返回的结果类型需要依据操作而论。。
8.4内存视图(memory views)
memoryview对象允许允许Python代码可以免去复制过程,直接从支持缓冲协议的对象内部提取数据。
classmemoryview(obj)
参考obj创建一个memoryview对象。obj必须支持缓冲协议,当其为内置对象时应该为字节或字节数组对象,
__eq__(exporter)
如果内存视图和导出器的形状相同,并且所有相应的值在使用结构语法解释操作数的相应格式代码时相等,则它们是相等的。
tobytes()
将缓冲器内的数据以字节字符串的格式输出。
>>> m =memoryview(b"abc")
>>> m.tobytes()
b'abc'
>>> bytes(m)
b'abc'
tolist()
将缓冲器内的元素作为列表元素输出。
>>> memoryview(b'abc').tolist()
[97, 98, 99]
>>> importarray
>>> a= array.array('d', [1.1,2.2,3.3])
>>> m=memoryview(a)
>>> m.tolist()
[1.1, 2.2, 3.3]
release()
释放由memoryview对象公开的底层缓冲区。
>>> m =memoryview(b'abc')
>>> m.release()
>>> m[0]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: operation forbidden on released memoryview object