1

我对 Python 有一个非常基本的疑问。当对象的引用计数增加时,是否有一个函数被调用?

我确信应该有一个双下划线方法,我可以在我的类中重写。基本上我正在寻找 Foo 类中的ref方法。

class Foo():
    def __ref__(self):
        print ("refcount increased by 1")

ref1 = Foo()
ref2 = ref1 # prints "refcount increased by 1"
ref3 = ref2 # prints "refcount increased by 1"

PS:我知道sys.getrefcount

4

2 回答 2

1

VM 没有为引用计数调用特殊方法。引用计数是 CPython VM 的实现细节,在特定于实现的帮助程序之外不可见。

引用计数(Python 词汇表)

对对象的引用数。当一个对象的引用计数下降到零时,它就会被释放。引用计数通常对 Python 代码不可见,但它是 CPython 实现的关键元素。该sys模块定义了一个getrefcount() 函数,程序员可以调用该函数来返回特定对象的引用计数。


CPython 在内部使用C 宏/函数来管理引用计数。对于 CPython 3.8,引用计数是一个 C 整数省略调试操作引用计数定义为

static inline void _Py_INCREF(PyObject *op)
{
    op->ob_refcnt++;
}

获取引用只会增加引用计数。这纯粹是一个 C 递增操作,在增加引用计数时不能调用任何 Python 代码

// omitting lineno/filename used for debug
static inline void _Py_DECREF(PyObject *op)
{
    _Py_DEC_REFTOTAL;
    if (--op->ob_refcnt != 0) {
    }
    else {
        _Py_Dealloc(op);
    }
}

释放引用会减少引用计数,并立即触发对未引用对象的取消分配。递减是纯粹的 C 递减操作,减少引用计数时不能调用任何 Python 代码。只有在将引用计数减为 0 后,才能_Py_Dealloc最终通过__del__.

于 2020-08-15T08:50:49.383 回答
1

没有这样的钩子。它会破坏各种东西,包括依赖于在不触发解释代码的情况下增加对象的能力的 C 级代码。它与不可引用的 Python 实现(其中大多数)不兼容。它将与任何假设的未来非引用 CPython 实现不兼容(不太可能如此)。它会与自身不兼容,因为仅仅调用或离开此类方法的行为就会改变对象的引用计数,要求它再次无限触发,并​​且在方法内对对象执行任何操作也会修改引用计数并导致另一个触发器即使您可以到达方法主体。

于 2020-07-21T10:28:23.103 回答