Reputation:
I was trying to figure out how python store the reference count of an object :
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
>>>
In my above snippet, as soon as i create a string object s
i got the ref-count 28, then when i assigned inside a dictionary its ref-count increment by one. And I don't know why it starts with 28.
So, Here I am trying to figure out where this values store or how python get it.
Thanks
Upvotes: 5
Views: 688
Reputation: 239473
You can get the list of referrers to your object, using gc.get_referrers
function, like this
import gc, pprint
pprint.pprint(gc.get_referrers("string"))
The reference count of each and every object is stored in the object itself, in a variable called ob_refcnt
typedef struct _object {
_PyObject_HEAD_EXTRA
Py_ssize_t ob_refcnt;
struct _typeobject *ob_type;
} PyObject;
And the Reference counts of the objects are incremented and decremented using the macros Py_INCREF
and Py_DECREF
respectively.
#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)
Upvotes: 5
Reputation: 280564
The reference count of an object is stored in the object itself, in the C-level ob_refcnt
field of the ob_base
field of the C struct representing the object. You can't access these fields, or at least not through anything like obj.ob_base.ob_refcnt
.
The documentation for PyObject is a bit out of date. I believe PEP 3123 has a more recent description of the PyObject type and PyObject_HEAD macros, but that might be out of date too. I would provide a source link, but I have no idea where these things are defined in the source.
Upvotes: 1
Reputation: 6727
Python uses same object for string literal which have the same value. Maybe, that's why you can see unexpectedly high ref count in your case.
For example, if I try to set 'string' literal to multiple string object, as you can see 's' object reference count keep increasing.
>>> s = 'string'
>>> sys.getrefcount(s)
2
>>> a = 'string'
>>> sys.getrefcount(s)
3
>>> b = 'string'
>>> sys.getrefcount(s)
4
Upvotes: 1