Garbage collection and Method redefinition

Tim Peters tim_one at email.msn.com
Tue Sep 19 19:29:10 EDT 2000


[Jesus Cea Avion]
> Python 1.5.2 here.
>
> I have the following class:
>
> class a:
>   def __init__(self):
>     self.func=self.func2
>   def func(self):
>     print "func"
>   def func2(self):
>     print "func2"
>   def __del__(self):
>     print "destroyed"
>
> Doing "b=a(); b.func()" prints "func2", correctly.
>
> My problem, nevertheless, is garbage collection: when you override a
> method in this way (or, for example, b.new=b.old), the refcounter is
> incremented and the instante won´t be garbage collected:

It's actually that you've created a cycle.  b.func2 is a "bound method
object", which wraps references to both func2 and to b itself.  This line:

    print b.func.im_self is b

prints "1" after the above:  b can be reached via a chain of references
starting from itself, and refcounting alone isn't strong enough to break
cycles.

> ...
> I need dynamic method overriding in order to improve the performance of
> some of my classes. For example "a.func()" has an initial
> implementation; when some events occurs, "a.func()" is redefined in
> order to skip some tests and internal method calls.
>
> What am I doing wrong?.

Well, you used the word "overriding" twice, but you're not doing any <wink>.
That is, the intended way to do overriding in Python is via subclassing.  If
you don't want to do that cleanly, you can rebind b.__class__ at runtime.

class _FastClass:
    ...
    def func(self):
        speedy
    ...

class _SlowClass(_FastClass):
    ...
    def func(self):
        sloooooooooooooooooow
    ...

a = _SlowClass

b = a()
b.func()   # uses slow func
b.__class__ = _FastClass
b.func()   # uses fast func

No cycles.

don't-give-me-that-look-*you're*-the-speed-at-any-cost-guy<wink>-ly
    y'rs  - tim





More information about the Python-list mailing list