有没有一种方法可以获取Python中某个对象的当前引用计数?


93

有没有一种方法可以获取Python中某个对象的当前引用计数?

Answers:



63

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

因此,len(gc.get_referrers(foo))将为您提供该列表的长度:引荐来源网址的数量,这是您所追求的。

另请参阅gc模块文档


7
还应该提到,计数将为+1,因为gc列表也引用了该对象。
理查德·勒瓦瑟

1
我认为@Dan答案是正确的:>>> import gc >>> class Bar():... pass ... >>> b = Bar()>>> len(gc.get_referrers(b)) 1 >>> gc.get_referrers(b)[{ 'b':<在0x7f1f010d0e18 __ main__.Bar实例>, '酒吧':<类标尺示在0x7f1f010d6530>, '建宏':<模块'内置'(内置in)>,“”:无,“ gc”:<模块“ gc”(内置)>,“名称”:“ main ”,“ doc ”:无}]
Havok

2
如果您确实只需要数字,则@tehvan的答案(sys.getrefcount(object))比更加简单len(gc.get_referrers(foo))
moi

在Android的qpython3中,它给出了错误的答案。每次。
Shihab Shahriar Khan

9

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)

然后function(SomeObject)交付“ 7”,
sub_function(SomeObject)交付“ 5”,
sub_sub_function(SomeObject)交付“ 3”和
sys.getrefcount(SomeObject)交付“ 2”。

换句话说:如果使用sys.getrefcount(),则必须知道函数的调用深度。因为gc.get_referrers()可能必须过滤引荐来源网址列表。

我建议出于“变更隔离”(即“如果在其他地方引用,则克隆”)之类的目的进行手动引用计数


5
import ctypes

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

ctypes.c_long.from_address(my_var_address).value

ctypes将变量的地址作为参数。与sys.getRefCount相比,使用ctypes的优势在于您无需从结果中减去1。


有趣的是,不应使用此方法:1)没有人会在阅读代码时了解发生了什么2)它取决于CPython的实现细节:id是对象的地址以及PyObject的确切内存布局。如果需要,只需从getrefcount()中减去1。
EAD
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.