147

Is there a way to get the current ref count of an object in Python?

5 Answers 5

158

According to the Python documentation, the sys module contains a function:

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

Generally 1 higher than you might expect, because of object arg temp reference.

Sign up to request clarification or add additional context in comments.

2 Comments

Link to the official documentation: docs.python.org/2/library/sys.html#sys.getrefcount
To explain the "1 higher" comment, calling a function creates a temporary reference to the variable used as the parameter.
87

Using the gc module, the interface to the garbage collector guts, you can call gc.get_referrers(foo) to get a list of everything referring to foo.

Hence, len(gc.get_referrers(foo)) will give you the length of that list: the number of referrers, which is what you're after.

See also the gc module documentation.

4 Comments

It should also be mentioned the count will be +1, since the gc list refers to the object, too.
I think @Dan that the answer is correct: >>> import gc >>> class Bar(): ... pass ... >>> b = Bar() >>> len(gc.get_referrers(b)) 1 >>> gc.get_referrers(b) [{'b': <__main__.Bar instance at 0x7f1f010d0e18>, 'Bar': <class main.Bar at 0x7f1f010d6530>, 'builtins': <module 'builtin' (built-in)>, 'package': None, 'gc': <module 'gc' (built-in)>, 'name': 'main', 'doc': None}]
@tehvan's answer (sys.getrefcount(object)) is more straightforward than len(gc.get_referrers(foo)), if you really only need the number.
in Android's qpython3, it gives wrong answer. every time.
13

There is gc.get_referrers() and sys.getrefcount(). But, It is kind of hard to see how sys.getrefcount(X) could serve the purpose of traditional reference counting. Consider:

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)

Then function(SomeObject) delivers '7',
sub_function(SomeObject) delivers '5',
sub_sub_function(SomeObject) delivers '3', and
sys.getrefcount(SomeObject) delivers '2'.

In other words: If you use sys.getrefcount() you must be aware of the function call depth. For gc.get_referrers() one might have to filter the list of referrers.

I would propose to do manual reference counting for purposes such as “isolation on change”, i.e. “clone if referenced elsewhere”.

1 Comment

It can serve the purpose of debugging reference counting errors.
9
import ctypes

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

ctypes.c_long.from_address(my_var_address).value

ctypes takes address of the variable as an argument. The advantage of using ctypes over sys.getRefCount is that you need not subtract 1 from the result.

1 Comment

While funny this method should not be used: 1) nobody will understand what is going on while reading the code 2) it depends on implementation details of CPython: id being the address of the object and the exact memory layout of a PyObject. Just substract 1 from getrefcount() if needed.
3

Every object in Python has a reference count and a pointer to a type. We can get the current reference count of an object with the sys module. You can use sys.getrefcount(object), but keep in mind that passing in the object to getrefcount() increases the reference count by 1.

import sys

name = "Steve"

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

2 Comments

Works for string values but for numeric values returns a weird long number 1000000011. Why?
@noob7 small numbers (range(-5,257)) are shared objects, which will never be released from memory and same numbers are the same object. It seems it is done by adding a big number to refcount. Adding big number can be safer if third-party C extension accidentally release one of them, and it is very clear it is actually kept.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.