Member of The Internet Defense League Últimos cambios
Últimos Cambios
Blog personal: El hilo del laberinto Geocaching

Garbage collection and Method Redefinition

Última Actualización: 26 de Septiembre de 2000 - Martes

Se incluye mi mensaje y la respuesta recibida:

Message-ID: <39C7EA93.1FDC0056@argo.es>
Date: Wed, 20 Sep 2000 00:37:07 +0200
From: Jesus Cea Avion <jcea@argo.es>
Organization: Argo Redes y Servicios Telematicos, S.A. - http://www.argo.es/
Newsgroups: comp.lang.python
Subject: Garbage collection and Method redefinition

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 instance won't be garbage collected:

>>> b=a()
>>> del b
>>> b=a()
>>> b.__del__()
destroyed
>>> print b
<__main__.a instance at 12bf20>

Is this a bug?

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?.

--
Jesus Cea Avion                         _/_/      _/_/_/        _/_/_/
jcea@argo.es http://www.argo.es/~jcea/ _/_/    _/_/  _/_/    _/_/  _/_/
                                      _/_/    _/_/          _/_/_/_/_/
PGP Key Available at KeyServ   _/_/  _/_/    _/_/          _/_/  _/_/
"Things are not so easy"      _/_/  _/_/    _/_/  _/_/    _/_/  _/_/
"My name is Dump, Core Dump"   _/_/_/        _/_/_/      _/_/  _/_/
"El amor es poner tu felicidad en la felicidad de otro" - Leibniz


Return-Path: <tim_one@email.msn.com>
Delivered-To: python-list@python.org
From: "Tim Peters" <tim_one@email.msn.com>
To: <python-list@python.org>
Subject: RE: Garbage collection and Method redefinition
Message-ID: <LNBBLJKPBEHFEDALKOLCKEAEHHAA.tim_one@email.msn.com>
In-Reply-To: <39C7EA93.1FDC0056@argo.es>
Date: Tue, 19 Sep 2000 19:29:10 -0400
Newsgroups: comp.lang.python

[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 . 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-ly
    y'rs  - tim



Python Zope ©2000 jcea@jcea.es

Más información sobre los OpenBadges

Donación BitCoin: 19niBN42ac2pqDQFx6GJZxry2JQSFvwAfS