📅  最后修改于: 2020-09-20 04:19:43             🧑  作者: Mango
在了解什么是内存视图之前,我们需要首先了解Python的缓冲区协议。
缓冲区协议提供了一种访问对象内部数据的方法。该内部数据是存储器阵列或缓冲区。
缓冲区协议允许一个对象公开其内部数据(缓冲区),而另一个协议无需中间复制即可访问这些缓冲区。
我们只能在C-API级别上访问此协议,而不能使用我们的常规代码库。
因此,为了将相同的协议公开给普通的Python代码库,需要使用内存视图。
内存视图是在Python公开缓冲区协议的安全方法。
它允许您通过创建内存视图对象来访问对象的内部缓冲区。
我们需要记住,每当对对象执行某些操作(调用对象的函数 ,切片数组)时, Python需要创建该对象的副本 。
如果我们要处理大量数据(例如,图像的二进制数据),则将不必要地创建大量数据的副本,这几乎毫无用处。
使用缓冲协议,我们可以授予另一个对象访问权以使用/修改大数据而无需复制它。这使程序使用更少的内存并提高了执行速度。
为了使用memoryview()
公开缓冲区协议,我们使用以下语法:
memoryview(obj)
memoryview()
函数采用单个参数:
obj
必须支持缓冲区协议(字节,字节数组) memoryview()
函数返回一个内存视图对象。
#random bytearray
random_byte_array = bytearray('ABC', 'utf-8')
mv = memoryview(random_byte_array)
# access memory view's zeroth index
print(mv[0])
# create byte from memory view
print(bytes(mv[0:2]))
# create list from memory view
print(list(mv[0:3]))
输出
65
b'AB'
[65, 66, 67]
在这里,我们从字节数组random_byte_array
创建了一个内存视图对象mv
。
然后,我们访问了mv
的第0个索引'A'
并进行了打印(给出ASCII值-65)。
再次,我们从0和1中访问了'AB'
的mv
索引,并将它们转换为字节。
最后,我们访问了mv
所有索引并将其转换为列表。由于内部bytearray
数组存储字母的ASCII值,因此输出为A
, B,
和C
的ASCII值列表。
# random bytearray
random_byte_array = bytearray('ABC', 'utf-8')
print('Before updation:', random_byte_array)
mv = memoryview(random_byte_array)
# update 1st index of mv to Z
mv[1] = 90
print('After updation:', random_byte_array)
输出
Before updation: bytearray(b'ABC')
After updation: bytearray(b'AZC')
在这里,我们将内存视图的第一个索引更新为90,即Z
的ASCII值。
由于内存视图对象mv
引用相同的缓冲区/内存,因此更新mv
的索引也会更新random_byte_array
。