我试图找出python如何存储对象的引用计数:
getrefcount(...)
getrefcount(object) -> integer
Return the reference count of object. The count returned is generally
one higher than you might expect, because it includes the (temporary)
reference as an argument to getrefcount().
>>>
>>> s = 'string'
>>> sys.getrefcount(s)
28
>>> d = {'key' : s}
>>> sys.getrefcount(s)
29
>>> l = [s]
>>> sys.getrefcount(s)
30
>>> del l
>>> sys.getrefcount(s)
29
>>> del d
>>> sys.getrefcount(s)
28
>>>
在我上面的代码片段中,一旦我创建了一个字符串对象s
,我得到了ref-count 28,然后当我在字典中分配它的ref-count增加1。我不知道为什么它从28开始。
所以,在这里,我试图找出这个值存储的位置或python如何获取它。
谢谢
答案 0 :(得分:5)
您可以使用gc.get_referrers
函数获取对象的引荐列表,如下所示
import gc, pprint
pprint.pprint(gc.get_referrers("string"))
每个对象的引用计数存储在对象本身中,名为ob_refcnt
typedef struct _object {
_PyObject_HEAD_EXTRA
Py_ssize_t ob_refcnt;
struct _typeobject *ob_type;
} PyObject;
对象的引用计数分别使用宏Py_INCREF
和Py_DECREF
递增和递减。
#define Py_INCREF(op) ( \
_Py_INC_REFTOTAL _Py_REF_DEBUG_COMMA \
((PyObject*)(op))->ob_refcnt++)
#define Py_DECREF(op) \
do { \
if (_Py_DEC_REFTOTAL _Py_REF_DEBUG_COMMA \
--((PyObject*)(op))->ob_refcnt != 0) \
_Py_CHECK_REFCNT(op) \
else \
_Py_Dealloc((PyObject *)(op)); \
} while (0)
答案 1 :(得分:2)
Python对字符串文字使用相同的对象,它具有相同的值。 也许,这就是为什么你可以在你的情况下看到意外的高重新计数。
例如,如果我尝试将'string'文字设置为多个字符串对象,因为您可以看到's'对象引用计数不断增加。
>>> s = 'string'
>>> sys.getrefcount(s)
2
>>> a = 'string'
>>> sys.getrefcount(s)
3
>>> b = 'string'
>>> sys.getrefcount(s)
4
答案 2 :(得分:0)
对象的引用计数存储在对象本身中,存储在表示对象的C结构的ob_refcnt
字段的C级ob_base
字段中。您无法访问这些字段,或者至少不能访问obj.ob_base.ob_refcnt
。
PyObject的文档有点过时了。我相信PEP 3123有更新的PyObject类型和PyObject_HEAD宏的描述,但这可能已经过时了。我会提供一个源链接,但我不知道在源中定义了这些内容。