2017-05-19 60 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