近日,在阅读《Fluent Python》的第2.9.2节时,有一个关于内存视图的例子,当时看的只知其一;不知其二,后来查了一些资料,如今总结一下,以备后续查询;html
添加了一些额外的代码,便于更好理解
memoryview
python
>>> import array >>> numbers = array.array('h', [-2, -1, 0, 1, 2]) >>> memv = memoryview(numbers) >>> len(memv) 5 >>> memv[0] -2 >>> memv_oct = memv.cast('B') >>> memv_oct <memory at 0x10869d7c8> >>> memv_oct.tolist() [254, 255, 255, 255, 0, 0, 1, 0, 2, 0] >>> memv.tolist() [-2, -1, 0, 1, 2] >>> memv_oct[5] = 4 >>> numbers array('h', [-2, -1, 1024, 1, 2]) >>> memv.tolist() [-2, -1, 1024, 1, 2] >>> memv_oct.tolist() [254, 255, 255, 255, 0, 4, 1, 0, 2, 0]
nembers
是一个signed short int
类型的数组;memv
是使用上述数组建立的一个memoryview,即内存视图,它使memv
可以共享nembers
数组的内存,但不须要复制里面的内容,这使得memv
也可以访问和操做numbers
数组的元素;memv[0] # -2
也就能够理解了。memv.cast('B')
把memv
转换成一个unsigned char int
的新memoryview
,并返回给memv_oct
。memv_oct.tolist()
的元素比原始数组多了一倍:
unsigned char int
在内存中则是1个字节存储。memv.tolist()
和numbers
的内容仍是同样的,因此memoryview
只是换个角度看同一个事物,即所谓的横当作岭侧成峰,远近高低各不一样signed short int
类型的-2
转换成unsigned char int
类型时,变成254 255
?memv_oct[5] = 4
将signed short int
类型的0
的高字节赋值成4
;在二进制的层面下看,即0000 0000 0000 0000
转换成了0000 0000 0010 0000
,十进制也就是1024;memv.tolist()
也随着numbers
改变了。更能说明memoryview
只是对同一块数据的进行不一样形式的表达;正整数的状况能够理解,负整数的状况就理解不了,这说明正负整数在内存中的存储形式是不同的。有了方向咱们就直接搜一下吧。编程
signed short int
类型的原码最高位表示正负,0
表明正数,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
;其实这都是《计算机组成原理》的基本知识,只是当咱们习惯了使用一些高级编程语言的时候,对于这些底层的东西就不那么敏感了。数组