python進階之內存模型


 

 

每一個編程語言的背后都有自己獨特的內存模型支持,比如最經典的C語言,一個int類型占8字節。那么在python中不區分數據類型,定義一個變量其在內存在占用多少字節呢?python中數據的運算其內存是如何變化的呢?

在回答上面的問題之前,首先看一下python中可變的數據和不可變數據


一、可變對象和不可變對象

Python一切數據皆為對象,python中的對象分成兩類:可變對象和不可變對象。所謂可變對象是指,對象的內容可變,而不可變對象是指對象內容不可變。

不可變(immutable):數值(int、float)、字符串(string)、元組(tuple)

可變(mutable):字典型(dictionary)、列表型(list) 

 

 

 

根據對象的分類,可以將數據類型也做一個分類,可變數據類型與不可變數據類型:

可變數據類型:列表list和字典dict 

不可變數據類型:整型int、浮點型float、字符串型string和元組tuple 

  

這里的可變不可變,是指內存中的那塊內容是否可以被改變。

如果是不可變類型,在對對象本身操作的時候,必須在內存中新申請一塊區域(因為老區域不可變)。創建a=1整型對象,執行a=2時,內存中的對象1是不變的,只是重新創建了對象2。

如果是可變類型,對對象操作的時候,不需要再在其他地方申請內存,只需要在此對象后面連續申請(+/-)即可,也就是它的內存地址會保持不變,但區域會變長或者變短。

 

當對可變和不可變對象運算時會內存中會發生什么事情呢?對比來看

不可變數據類型:不允許變量的值發生變化,如果改變了變量的值,相當於是新建了一個對象,而對於相同的值的對象,在內存中則只有一個對象,內部會有一個引用計數來記錄有多少個變量引用這個對象; 
可變數據類型:允許變量的值發生變化,即如果對變量進行append、+=等這種操作后,只是改變了變量的值,而不會新建一個對象,變量引用的對象的地址也不會變化,不過對於相同的值的不同對象,在內存中則會存在不同的對象,即每個對象都有自己的地址,相當於內存中對於同值的對象保存了多份,這里不存在引用計數,是實實在在的對象。

 

python對於數據的特殊處理 

 

小整數

Python為了優化速度,避免為整數頻繁申請和銷毀內存空間,使用了小整數對象池。對小整數的定義是 [-5, 256] 這些整數對象是提前建立好的,不會被垃圾回收。在這個范圍內所有的整數都只會被建立一次。

 

a = 100
b = 100
print(id(a))
print(id(b))

-------------------------
94125443429088
94125443429088

  

a = 200
b = 200 

print a is b 
-----------------
True


a = 300
b = 300
print a is b
-----------------
False

 

大整數

大整數池: 只存儲包含標准字符(數字、字母、下划線)的字符串,不包含特殊字符的字符串 。

python為了避免創建大整數浪費的內存空間和時間,將創建過的大整數加入大整數池。

python中大整數池,默認大整數池里面為空,每一個py程序都有一個大整數池。使用大整數時如果大整數池里不存在該整數的話,會新建一個大整數對象。下次使用大整數時直接使用大整數池里的對象,而不是創建新的對象 

py文件中,每次運行時都會將所有代碼加載到內存中,屬於一個整體,因此處於同一個代碼塊的大整數是同一個對象,所以兩者id是一樣的。

a = '12345'
b = '12345'

print id(a)
print id(b)
-----------------------------
140139908067808
140139908067808


print a is b
-----------------------------
True

 

其他數據類型

如果是其他普通類型對象的新建,python會請求內存,申請內存 。當n1的引用指向其他對象時,原有對象的引用計數會自動減1,沒有被引用的對象會立即回收。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM