您好,登錄后才能下訂單哦!
Python中怎么引用計數,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
回顧內存地址
Python中的任何變量都有對應的內存引用,也就是內存地址。
如果不是容器類型,那么直接引用和賦值,內存地址都是不會的。
>>> a = 1 >>> b = 1 >>> id(a) 140709385600544 >>> id(b) 140709385600544
如果在內存中創建了一個list對象(容器),而且對該對象進行了引用。那么b = [1,2]和c = a有什么區別?
>>> a = [1,2] >>> b = [1,2] >>> id(a) 1966828025736 >>> id(b) 1966828044488 >>> c = a >>> id(c) 1966828025736
首先在內存1966828025736處創建了一個列表 [1,2],然后定義了一個名為a的變量。b = [1,2]會新開一個內存地址,c = a直接賦值直接引用[1,2]的內存地址。
引用計數
在一些代碼中,如果存在一些變量但是沒有用,會造成內存空間,因此叫做垃圾,所以要回收。
引用計數也是一種最直觀,最簡單的垃圾收集技術。原理非常簡單,每一個對象都包含了兩個頭部信息,一個是類型標志符,標識這個對象的類型;另一個是計數器,記錄當前指向該對象的引用數目,表示這個對象被多少個變量名所引用。
CPython 使用引用計數來管理內存,所有 Python 腳本中創建的實例,都會有一個引用計數,來記錄有多少個指針指向它。當引用計數只有 0 時,則會自動釋放內存。
在Python中通過sys.getrefcount查看引用計數的方法,
print(sys.getrefcount())
注意調用getrefcount()函數會臨時增加一次引用計數,得到的結果比預期的多一次。
比如,下面這個例子中,a 的引用計數是 3,因為有 a、b 和作為參數傳遞的 getrefcount 這三個地方,都引用了一個空列表。
>>> import sys >>> a = [] >>> b = a >>> print(sys.getrefcount(a)) 3
我們通過一些例子來看下,可以使python對象的引用計數增加或減少的場景。
import sys a = [] # 兩次引用,一次來自 a,一次來自 getrefcount print(sys.getrefcount(a)) def func(a): # 四次引用,a,python 的函數調用棧,函數參數,和 getrefcount print(sys.getrefcount(a)) func(a) # 兩次引用,一次來自 a,一次來自 getrefcount,函數 func 調用已經不存在 print(sys.getrefcount(a)) ########## 輸出 ########## 2 4 2
引用計數是用來記錄對象被引用的次數,每當對象被創建或者被引用時將該對象的引用次數加一,當對象的引用被銷毀時該對象的引用次數減一,當對象的引用次數減到零時說明程序中已經沒有任何對象持有該對象的引用,換言之就是在以后的程序運行中不會再次使用到該對象了,那么其所占用的空間也就可以被釋放了了。
計數增加和減少
下面引用計數增加的場景:
對象被創建并賦值給某個變量,比如:a = 'ABC'
變量間的相互引用(相當于變量指向了同一個對象),比如:b=a
變量作為參數傳到函數中。比如:ref_method(a),
將對象放到某個容器對象中(列表、元組、字典)。比如:c = [1, a, 'abc']
引用計數減少的場景:
當一個變量離開了作用域,比如:函數執行完成時,執行方法前后的引用計數保持不變,這就是因為方法執行完后,對象的引用計數也會減少,如果在方法內打印,則能看到引用計數增加的效果。
對象的引用變量被銷毀時,比如del a或者del b。注意如果del a,再去獲取a的引用計數會直接報錯。
對象被從容器對象中移除,比如:c.remove(a)
直接將整個容器銷毀,比如:del c
對象的引用被賦值給其他對象,相當于變量不指向之前的對象,而是指向了一個新的對象,這種情況,引用計數肯定會發生改變。(排除兩個對象默認引用計一致的場景)。
import sys def ref_method(str): print(sys.getrefcount(str)) print("我調用了{}".format(str)) print('方法執行完了') def ref_count(): # 引用計數增加的場景 print('測試引用計數增加') a = 'A' print(sys.getrefcount(a)) b = a print(sys.getrefcount(a)) ref_method(a) print(sys.getrefcount(a)) c = [1, a, 'abc'] print(sys.getrefcount(a)) # 引用計數減少的場景 print('測試引用計數減少') del b print(sys.getrefcount(a)) c.remove(a) print(sys.getrefcount(a)) del c print(sys.getrefcount(a)) a = 783 print(sys.getrefcount(a)) if __name__ == '__main__': ref_count() ########## 輸出 ########## 測試引用計數增加 78 #77+1 77在函數中是隨機的 79 81 我調用了A 方法執行完了 79 80 測試引用計數減少 79 78 78 4
關于Python中怎么引用計數問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。