有没有办法在Python中获取对象的当前引用计数?

74 python refcounting

有没有办法在Python中获取对象的当前引用计数?

teh*_*van 88

根据Python 文档,该sys模块包含一个函数:

import sys
sys.getrefcount(object) #-- Returns the reference count of the object.
Run Code Online (Sandbox Code Playgroud)

由于对象arg临时引用,通常比您预期的高1.


kqu*_*inn 58

使用gc模块,垃圾收集器内核的接口,您可以调用gc.get_referrers(foo)以获取所有引用的列表foo.

因此,len(gc.get_referrers(foo))将为您提供该列表的长度:引用者的数量,这是您所追求的.

另请参见gc模块文档.

  • 还应该提到计数将是+1,因为gc列表也引用了对象. (7认同)
  • @tehvan 的答案 (`sys.getrefcount(object)`) 比 `len(gc.get_referrers(foo))` 更直接,如果你真的只需要数字。 (2认同)

Fra*_*fer 7

gc.get_referrers()sys.getrefcount().但是,很难看出如何sys.getrefcount(X)能够达到传统参考计数的目的.考虑:

import sys

def function(X):
    sub_function(X)

def sub_function(X):
    sub_sub_function(X)

def sub_sub_function(X):
    print sys.getrefcount(X)
Run Code Online (Sandbox Code Playgroud)

然后function(SomeObject)提供'7',
sub_function(SomeObject)提供'5',
sub_sub_function(SomeObject)提供'3',并
sys.getrefcount(SomeObject)提供'2'.

换句话说:如果使用sys.getrefcount(),则必须了解函数调用深度.因为gc.get_referrers()可能必须过滤引用列表.

我建议进行手动引用计数,例如"隔离更改",即"如果在别处引用则克隆".


小智 7

import ctypes

my_var = 'hello python'
my_var_address = id(my_var)

ctypes.c_long.from_address(my_var_address).value
Run Code Online (Sandbox Code Playgroud)

ctypes 将变量的地址作为参数。使用 ctypes 优于 sys.getRefCount 的优点是您不需要从结果中减去 1。

  • 虽然有趣,但不应使用此方法:1)没有人会理解阅读代码时发生的情况2)它取决于 CPython 的实现细节:id 是对象的地址和 PyObject 的确切内存布局。如果需要,只需从 getrefcount() 中减去 1 即可。 (4认同)