《Fluent|《Fluent Python》---一个关于memoryview例子的理解过程
近日,在阅读《Fluent Python》的第2.9.2节时,有一个关于内存视图的例子,当时看的一知半解,后来查了一些资料,现在总结一下,以备后续查询;示例复述
添加了一些额外的代码,便于更好理解memoryview
>>> 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
>>> 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()
的元素比原始数组多了一倍:- signed short int在内存中是以2个字节存储,而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
只是对同一块数据的进行不同形式的表达;
【《Fluent|《Fluent Python》---一个关于memoryview例子的理解过程】正整数的情况可以理解,负整数的情况就理解不了,这说明正负整数在内存中的存储形式是不一样的。有了方向我们就直接搜一下吧。
-
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
;
推荐阅读
- 慢慢的美丽
- 《真与假的困惑》???|《真与假的困惑》??? ——致良知是一种伟大的力量
- 《跨界歌手》:亲情永远比爱情更有泪点
- 诗歌:|诗歌: 《让我们举起世界杯,干了!》
- 期刊|期刊 | 国内核心期刊之(北大核心)
- 《魔法科高中的劣等生》第26卷(Invasion篇)发售
- 人间词话的智慧
- 《一代诗人》37期,生活,江南j,拨动心潭的一泓秋水
- 广角叙述|广角叙述 展众生群像——试析鲁迅《示众》的展示艺术
- 书评——《小行星》