Reference Cycles with instance method

Peter Otten __peter__ at web.de
Wed Mar 9 03:14:50 EST 2011


Amit Dev wrote:

> Simple question. If I have the following code:
> 
> class A:
>     def __init__(self, s):
>         self.s = s
>         self.m2 = m1
> 
>     def m1(self):
>         pass
> 
> if __name__ == '__main__':
>     a = A("ads")
>     a.m1()
>     a = None
> 
> The object is not garbage collected, since there appears to be a cycle
> (between method m2 and A). I would expect this to behave the same as
> having another method "def m2(self): self.m1()", but unfortunately its
> not.
> In above case m2 seems to be in a.__dict__ which is causing the cycle.
> Any idea why this is so?

Hm, I get a NameError

Traceback (most recent call last):
  File "tmp.py", line 10, in <module>
    a = A("ads")
  File "tmp.py", line 4, in __init__
    self.m2 = m1
NameError: global name 'm1' is not defined

In general self.some_method returns a bound method which holds a reference 
to both the some_method function and the instance:

>>> class A:
...     def m(self): print "M"
...
>>> a = A()
>>> am = a.m
>>> am.__self__, am.__func__
(<__main__.A instance at 0x7f91c040e638>, <function m at 0x7f91c03f8b18>)

Therefore something like a.mm = a.m will create a reference cycle.



More information about the Python-list mailing list