0

I am trying to understand how the refcounts work in python, Can someone explain why the count gets printed as 2 when its just 1 instance for the object? (is it because of the temporary being passed to the getrefcount method?) Also why is the number more when invoked when invoked from the member (is self reference bumping the refcount?)

import sys

class A:
    def print_ref_count(self):
        print sys.getrefcount(self)

a = A()
print sys.getrefcount(a)   # prints 2
a.print_ref_count()        # prints 4
print sys.getrefcount(a)   # prints 2

1 Answer 1

2

There are implicit reference increments everywhere in Python. When you pass a as an argument to a function, it is incref-ed, as getrefcount's own docstring notes:

The count returned is generally one higher than you might expect, because it includes the (temporary) reference as an argument to getrefcount().

The two additional references when you invoke the method are, respectively:

  1. The reference held by the name self within the method
  2. The implicit reference created when it makes a bound method object specific to that instance when you do a.print_ref_count (even before actually calling it); type(a.print_ref_count) is a temporary bound method, which must include references to both the instance and the method itself (you could do to_print = a.print_ref_count, then del a, and to_print must still work even though a is no longer referencing the instance)

Getting hung up on the reference counts is not very helpful though; it's an implementation detail of Python (CPython specifically; other Python interpreters can and do use non-reference counting garbage collection), and as you can see, many implicit references are created that may not actually be stored in named variables at all.

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

1 Comment

Side-note: It is possible to get a ref count of 1, you just need to create the object solely for the purpose of ref counting it (and the object can't be an immutable literal that would be stored in the constants of a function, the empty tuple or a non-empty tuple of immutable literals, etc.). So sys.getrefcount(A()) would get you 1, as would sys.getrefcount(''.join(('a', 'b', 'c'))) (join needed to avoid interned literal), though neither would be very helpful.

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.