Python memoryview()

在我们了解内存视图是什么之前,我们需要首先了解 Python 的缓冲区协议。


Python 缓冲区协议

缓冲区协议提供了一种访问对象内部数据的方式。这个内部数据是一个内存数组或一个缓冲区。

缓冲区协议允许一个对象暴露其内部数据(缓冲区),另一个对象访问这些缓冲区而无需中间复制。

此协议只能在 C-API 级别访问,而不能使用我们普通的 codebase。

因此,为了将相同的协议暴露给普通的 Python codebase,内存视图应运而生。


什么是内存视图?

内存视图是 Python 中暴露缓冲区协议的一种安全方式。

它允许您通过创建内存视图对象来访问对象的内部缓冲区。


为什么缓冲区协议和内存视图很重要?

我们需要记住,每当我们对一个对象执行某些操作(调用对象的函数切片数组)时,Python 都需要创建对象的副本

如果我们要处理大量数据(例如图像的二进制数据),我们就会不必要地创建大量数据块的副本,这几乎毫无用处。

使用缓冲区协议,我们可以让另一个对象访问/修改大数据而无需复制它。这使得程序占用更少的内存并提高了执行速度。


Python memoryview() 语法

要使用 memoryview() 暴露缓冲区协议,我们使用以下语法

memoryview(obj)

memoryview() 参数

memoryview() 函数接受一个参数

  • obj - 其内部数据要暴露的对象。obj 必须支持缓冲区协议(bytesbytearray

memoryview() 的返回值

memoryview() 函数返回一个内存视图对象。


示例 1:memoryview() 在 Python 中如何工作?

#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)。

再次,我们访问了 mv 的第 0 和第 1 个索引,即 'AB',并将它们转换为字节。

最后,我们访问了 mv 的所有索引并将其转换为列表。由于 bytearray 内部存储字母的 ASCII 值,因此输出是 ABC 的 ASCII 值列表。


示例 2:使用内存视图修改内部数据

# 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')

在这里,我们将内存视图的第 1 个索引更新为 90,即 Z 的 ASCII 值。

由于内存视图对象 mv 引用了相同的缓冲区/内存,因此更新 mv 中的索引也会更新 random_byte_array

你觉得这篇文章有帮助吗?

我们的高级学习平台,凭借十多年的经验和数千条反馈创建。

以前所未有的方式学习和提高您的编程技能。

试用 Programiz PRO
  • 交互式课程
  • 证书
  • AI 帮助
  • 2000+ 挑战