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

136

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

5个回答

149

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

import sys
sys.getrefcount(object) #-- Returns the reference count of the object.

通常比你预期的高 1,因为存在对象参数临时引用。


1
官方文档链接:https://docs.python.org/2/library/sys.html#sys.getrefcount - moi
1
解释“1 higher”的注释,调用函数会创建一个对用作参数的变量的临时引用。 - Mark Ransom

82
使用gc模块,这个接口是垃圾收集器的核心,你可以调用gc.get_referrers(foo)来获取一个列表,其中包含所有引用foo的内容。
因此,len(gc.get_referrers(foo))将给出该列表的长度:引用数,这正是您想要的。
另请参阅gc模块文档

13
还应该提到,计数器会增加1,因为gc列表也涉及到该对象。 - Richard Levasseur
1
我认为@Dan的答案是正确的:>>> import gc >>> class Bar(): ... pass ... >>> b = Bar() >>> len(gc.get_referrers(b)) 1 >>> gc.get_referrers(b) [{'b': <__main__.Bar instance at 0x7f1f010d0e18>, 'Bar': , '__builtins__': , '__package__': None, 'gc': , '__name__': '__main__', '__doc__': None}] - Havok
3
@tehvan的回答(sys.getrefcount(object))比len(gc.get_referrers(foo))更直接,如果你只需要数量。 - moi
在Android的qpython3中,它每次都会给出错误的答案。 - Shihab Shahriar Khan

13

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(),你可能需要过滤引用者列表。

我建议对于像“更改隔离”这样的目的进行手动引用计数,即“克隆如果在其他地方被引用”。


9
import ctypes

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

ctypes.c_long.from_address(my_var_address).value

ctypes以变量的地址作为参数。使用ctypessys.getRefCount更好的优点是你不需要从结果中减去1。


10
虽然有趣,但不应使用此方法:1)在阅读代码时,没有人会理解发生了什么;2)它依赖于CPython的实现细节:id是对象的地址和PyObject的确切内存布局。如果需要,只需从getrefcount()中减去1。 - ead

2

在Python中,每个对象都有一个引用计数和指向类型的指针。 我们可以使用sys模块获取对象的当前引用计数。您可以使用sys.getrefcount(object)但请注意,将对象传递给getrefcount()会使引用计数增加1

import sys

name = "Steve"

# 2 references, 1 from the name variable and 1 from getrefcount
sys.getrefcount(name)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接