如果你总是跟数组打交道,却没有听过 memoryview
,那就太遗憾了。下面就来谈谈memoryview
。
memoryview
是一个内置类,它能让用户在不复制内容的情况下操作同一个数组的不同切片。memoryview
的概念受到了 NumPy
的启发。Travis Oliphant
是 NumPy
的主要作者,他在回答“ When should a memoryview be used?”
(http://stackoverflow.com/
questions/4845418/when-should-a-memoryview-be-used/)这个问题时是这样说的: 内存视图其实是泛化和去数学化的 NumPy
数组。它让你在不需要复制内容的前提下,在数据结构之间共享内存。其中数据结构可以是任何形式,比如 PIL
图片、SQLite
数据库和 NumPy
的数组,等等。这个功能在处理大型数据集合的时候非常重要。
memoryview.cast
的概念跟数组模块类似,能用不同的方式读写同一块内存数据,而且内容字节不会随意移动。这听上去又跟 C
语言中类型转换的概念差不多。memoryview.cast
会把同一块内存里的内容打包成一个全新的 memoryview
对象给你。
在如下示例里,我们利用 memoryview
精准地修改了一个数组的某个字节,这个数组的元素是 16 位二进制整数。
# -*- coding: utf-8 -*-
# 通过改变数组中的一个字节来更新数组里某个元素的值
from array import array
numbers = array('h', [-2, -1, 0, 1, 2])
memv = memoryview(numbers) # 利用含有 5 个短整型有符号整数的数组(类型码是 'h')创建一个 memoryview。
print(len(memv))
# 5
print(memv[0]) # memv 里的 5 个元素跟数组里的没有区别
# -2
memv_oct = memv.cast('B') # 创建一个 memv_oct,这一次是把 memv 里的内容转换成 'B' 类型,也就是无符号字符。
memv_oct.tolist() # 以列表的形式查看 memv_oct 的内容
memv_oct[5] = 4 # 把位于位置 5 的字节赋值成 4。
print(numbers) # 因为我们把占 2 个字节的整数的高位字节改成了 4,所以这个有符号整数的值就变成了 1024。
# array('h', [-2, -1, 1024, 1, 2])