2017-05-19 35 views
0

我想了解如何在Python中refcounts工作,有人可以解釋爲什麼計數得到打印爲2時,其對象只是1實例? (是不是因爲臨時被傳遞給getrefcount方法?)此外爲什麼當從成員調用時調用的數量多(自基準碰撞引用計數?)Refcount python objects

import sys 

class A: 
    def print_ref_count(self): 
     print sys.getrefcount(self) 

a = A() 
print sys.getrefcount(a) # prints 2 
a.print_ref_count()  # prints 4 
print sys.getrefcount(a) # prints 2 

回答

2

有隱式引用增量無處不在在Python中。當你通過a作爲參數傳遞給一個函數,它是incref-ED,如getrefcount自己的文檔字符串說明:

返回的計數是通常一個高於你所期望的,因爲它包含了(臨時)作爲getrefcount()的參數引用。

當你調用該方法的兩個額外的引用分別是:

  1. 方法中的名稱爲self舉行的參考
  2. 時,它使一個綁定方法對象特定創建的隱式引用當你做a.print_ref_count時(甚至在實際調用之前); type(a.print_ref_count)是一個臨時綁定的方法,其中必須包括的實例和方法本身都引用(你可以做to_print = a.print_ref_count,然後del a,並且to_print還必須工作,即使a不再引用實例)

獲取掛在參考計數是不是很有幫助,雖然;它是Python的實現細節(CPython專用;其他Python解釋器可以並且確實使用非引用計數垃圾回收),並且您可以看到,創建了許多隱式引用,它們可能根本不存儲在命名變量中。

+0

注意:有可能得到1的ref值,你只需要創建對象,僅僅是爲了ref計數它的目的(並且對象不能是一個不可變的文字,將被存儲在函數的常量,空的「元組」或不可變的文字的非空元組等)。所以'sys.getrefcount(A())'會讓你1,就像'sys.getrefcount(''。join(('','b','c')))'('join'需要避免字面意思),儘管這兩者都不會很有幫助。 – ShadowRanger