当我们要引用字节数据的某个片段(注意是对象内的某一个片段)的时候,可用内存视图直接引用目标内存,没有额外的复制行为,因此,可读取最新的数据,在目标对象允许的情况下,还可以执行写操作。若是还想要把目标复制出来,可以用tobytes、tolist 方法,复制后的数据与原对象无关,同样不会影响视图本身。
内存视图是泛化和去数学化的 NumPy 数组。它让你在不需要复制内容的前提下,在数据结构之间共享内存。其中数据结构可以是任何形式,比如 PIL 图片、SQLite 数据库和 NumPy 的数组,等等。这个功能在处理大型数据集合的时候非常重要。
memoryview 是一个内置类,它能让用户在不复制内容的情况下操作同一个数组的不同切片。
语法:memoryview(obj)
obj:字节对象或字节数组对象
memoryview.cast 功能是将字节数组转换为其它目标类型(后续会学习到)。
eg(利用 memoryview 精准地修改了一个数组的某个字节,这个数组的元素是 16 位二进制整数。):
>>> numbers = array.array('h', [-2, -1, 0, 1, 2]) #使用array
>>> memv = memoryview(numbers) #利用含有 5 个短整型有符号整数的数组(类型码是 'h')创建一个 memoryview
>>> len(memv)
5
>>> memv[0] #memv 里的 5 个元素跟数组里的没有区别
-2
>>> memv_oct = memv.cast('B') #创建一个 memv_oct,这一次是把 memv 里的内容转换成 'B' 类型,也就是无符号字符
>>> memv_oct.tolist() #以列表的形式查看 memv_oct 的内容
[254, 255, 255, 255, 0, 0, 1, 0, 2, 0] #详看计算机原理吧,这里涉及到各种补码、进制转换之类的东西,这里符号也转换成了一个数字,所以数量是原数组的两倍
>>> memv_oct[5] = 4 #把位于位置 5 的字节赋值成 4
>>> numbers
array('h', [-2, -1, 1024, 1, 2]) #因为我们把占 2 个字节的整数的高位字节改成了 4,所以这个有符号整数的值就变成了 1024。
memv_oct.tolist()产生的元素比原始数组多了一倍?
memv.cast(‘B’)把memv转换成一个unsigned char int的新memoryview,并返回给memv_oct。signed short int在内存中是以2个字节存储,而unsigned char int在内存中则是1个字节存储。
signed short int类型的原码最高位表示正负,0代表正数,1代表负数。它们内存中是以补码的形式存储的,其中正数的补码和原码相同;负数的补码,是其原码除符号位(即最高位,也就是最后一位)外,其余全部取反,再加1。
所以,signed short int类型的-2,其原码为0100 0000 0000 0001,除符号位取反,为1011 1111 1111 1111,再加1,为0111 1111 1111 1111。当以unsigned char int类型读出来的时候,就成了254 255了;-1亦是同理,即255 255(我记得计算机原理学过这个东西,有兴趣可以深入了解一下)
本次分享就到这里啦,后续会有关于这个知识点更深入的学习,持续更新中,有什么问题欢迎大家指出,我一定及时修改