近日,在閱讀《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
;其實這都是《計算機組成原理》的基本知識,只是當咱們習慣了使用一些高級編程語言的時候,對於這些底層的東西就不那麼敏感了。數組