近日,在閱讀《Fluent Python》的第2.9.2節(jié)時(shí)瘫里,有一個(gè)關(guān)于內(nèi)存視圖的例子实蔽,當(dāng)時(shí)看的一知半解,后來(lái)查了一些資料谨读,現(xiàn)在總結(jié)一下局装,以備后續(xù)查詢;
示例復(fù)述
添加了一些額外的代碼劳殖,便于更好理解
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
<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
是一個(gè)signed short int
類型的數(shù)組铐尚; -
memv
是使用上述數(shù)組創(chuàng)建的一個(gè)memoryview,即內(nèi)存視圖哆姻,它使memv
能夠共享nembers
數(shù)組的內(nèi)存塑径,但不需要復(fù)制里面的內(nèi)容,這使得memv
也能夠訪問(wèn)和操作numbers
數(shù)組的元素填具;memv[0] # -2
也就可以理解了统舀。 -
memv.cast('B')
把memv
轉(zhuǎn)換成一個(gè)unsigned char int
的新memoryview
,并返回給memv_oct
劳景。 -
memv_oct.tolist()
的元素比原始數(shù)組多了一倍:- signed short int在內(nèi)存中是以2個(gè)字節(jié)存儲(chǔ)誉简,而unsigned char int在內(nèi)存中則是1個(gè)字節(jié)存儲(chǔ)。
-
memv.tolist()
和numbers
的內(nèi)容還是一樣的盟广,所以memoryview
只是換個(gè)角度看同一個(gè)事物闷串,即所謂的橫看成嶺側(cè)成峰,遠(yuǎn)近高低各不同 - 至此筋量,我有一個(gè)不理解的地方:為什么
signed short int
類型的-2
轉(zhuǎn)換成unsigned char int
類型時(shí)烹吵,變成254 255
?
-
memv_oct[5] = 4
將signed short int
類型的0
的高字節(jié)賦值成4
桨武;在二進(jìn)制的層面下看肋拔,即0000 0000 0000 0000
轉(zhuǎn)換成了0000 0000 0010 0000
,也就是呀酸,即1024凉蜂; - 同時(shí),我們也可以看到
memv.tolist()
也隨著numbers
改變了。更能說(shuō)明memoryview
只是對(duì)同一塊數(shù)據(jù)的進(jìn)行不同形式的表達(dá)窿吩;
解惑
正整數(shù)的情況可以理解茎杂,負(fù)整數(shù)的情況就理解不了,這說(shuō)明正負(fù)整數(shù)在內(nèi)存中的存儲(chǔ)形式是不一樣的纫雁。有了方向我們就直接搜一下吧煌往。
-
signed short int
類型的原碼最高位表示正負(fù),0
代表正數(shù)轧邪,1
代表負(fù)數(shù)刽脖。 - 它們內(nèi)存中是以補(bǔ)碼的形式存儲(chǔ)的,其中正數(shù)的補(bǔ)碼和原碼相同闲勺;負(fù)數(shù)的補(bǔ)碼曾棕,是其原碼除符號(hào)位(即最高位)外,其余全部取反菜循,再加1翘地;
-
signed short int
類型的-2
,其原碼為0100 0000 0000 0001
癌幕,除符號(hào)位取反衙耕,為1011 1111 1111 1111
,再加1勺远,為0111 1111 1111 1111
橙喘。當(dāng)以unsigned char int
類型讀出來(lái)的時(shí)候,就成了254 255
了胶逢;-1
亦是同理厅瞎,即255 255
;
總結(jié)
其實(shí)這都是《計(jì)算機(jī)組成原理》的基本知識(shí)初坠,只是當(dāng)我們習(xí)慣了使用一些高級(jí)編程語(yǔ)言的時(shí)候和簸,對(duì)于這些底層的東西就不那么敏感了。