One Python 2.1 idea
Tim Peters
tim.one at home.com
Wed Dec 27 03:30:36 EST 2000
[Tim]
> Note:
>
> >>> class Oops:
> def foo(self):
> pass
>
> >>> x = Oops()
> >>> x.foo = x.foo
> >>> x.foo.im_self is x
> 1
> >>>
>
> Oops! That is, x is now involved in a reference cycle (x's
> dict contains a bound method that points back to x). Before 2.0,
> that's a memory leak. In 2.0, it's a leak only if the class
> (unlike Oops above) has a __del__ method (or you've disabled
> cyclic gc).
[Darrell Gallion]
> You lost me here Tim.
> ...
> Don't see what's changed after a.f=a.f
The right-hand side a.f found Oops.__dict__['f'], and made a bound method
object out of it and a. The left-hand side a.f makes that bound method the
value of a.__dict__['f'] (not in Oops's dict again, but in a's dict!). So
what changed is that a.__dict__.has_key('f') was false before "a.f = a.f",
but is true after. And a.__dict__['f'].im_self is a.
Why you changed all the names from the orginal example isn't clear or
helpful, so I'll add a few lines to the original instead:
>>> class Oops:
def foo(self): pass
>>> x = Oops()
>>> x.__dict__ # the instance dict is empty at the start
{}
>>> x.foo = x.foo # but this puts something into it
>>> x.__dict__
{'foo': <method Oops.foo of Oops instance at 00B24FDC>}
>>> x.__dict__['foo'].im_self is x # this is the cycle
1
>>> Oops.__dict__['foo'] # in Oops's dict, it's just a function
<function foo at 00B1E6FC>
>>> Oops.foo # but accessing a class dict via attr notation does magic
<unbound method Oops.foo>
>>>
This is pretty deep magic! Don't go doing things like "a.f=a.f", and you
can safely ignore it for decades.
and-writing-"x=x"-can-erase-your-hard-drive<wink>-ly y'rs - tim
More information about the Python-list
mailing list