内存视图(Memoryview)
内存视图对象到底是什么?先来看看官方手册上怎么说:
内存视图允许Python代码不用拷贝就能访问那些支持缓冲区协议的对象的内部数据。
这相当含糊。作为一个定义,它应该明确告诉我们它的表示形式,内容,怎么创建?啥作用以及啥时候使用它?
我试着来定义它。
有一个已经存在的原生数据块对象,比如字节,字节数组或者Numpy中的数组,这些对象有缓冲区协议定义的特性,可以用缓冲区协议定义的方法和特性来操作它们,python就利用这些协议,赋予这些原生数据新的意义和操作(它们并没有改变),从操作层面看,就像有了一个新的对象,我们就把它定义为原生对象的内存视图。
这里提到的缓冲区协议,我仔细看了PEP3118,它用C语言定义了一系列的函数,这些函数可以对内存的缓冲区进行各种操作。
它的数据实际还是原生对象的数据,但是读写的方式变了。很遗憾,可能因为比较复杂的原因,python并没像其它对象那样,给出内存视图一个直观的表示形式。
内存视图支持用切片和索引来暴露数据,一维切片产生一个子视图。
>>> v = memoryview(b'abcefg')
>>> print(v[1],v[-1])
98 103
>>> v[1:4]
>>> bytes(v[1:4])
b'bce'
其它原生格式的内存视图:
>>> import array
>>> a = array.array('l', [-1, 2, -3, -4])
>>> a[2:3].tolist()
[-3]
从上面可以看出它的表示形式就是memoryview(obj)。
如果底层对象可写,则内存视图支持一维切片赋值,但不能改变切片大小。
>>> data = bytearray(b'abcefg')
>>> v = memoryview(data)
>>> v[0] = ord(b'z')
bytearray(b'zbcefg')
>>> v[1:4] = b'123'
bytearray(b'z123fg')
>>> v[2:3] = b'spam' #赋值超过了切片元素个数
Traceback (most recent call last):
File"
", line 1, in
v[2:3] = b'spam'
ValueError: memoryview assignment: lvalue and rvaluehave different structures
这几天集中精力把这个内存视图搞清楚,然后补上。