Instance method decorator garbage collection problem
John Reid
j.reid at mail.cryst.bbk.ac.uk
Wed Jun 23 08:56:34 EDT 2010
Thomas Jollans wrote:
>> The InstanceCounted.count is 1 at the end. If I omit the call to
>> "self.method = print_exception_decorator(self.method)" then the instance
>> count goes down to 0 as desired. I thought that the decorator might be
>> holding a reference to the instance through the bound method, so I added
>> the __del__() but it doesn't fix the problem.
>
> Adding __del__ like this does "fix the problem", but it introduces a new
> one: lacking a call to super().__del__, you simply don't decrement the
> instance count.
Now that's a good point! I've added super().__del__ but the problem
remains for some reason. My A class now looks like:
class A(InstanceCounted):
"A class that I want to decorate a method on."
def __init__(self):
super(A, self).__init__()
self.method = print_exception_decorator(self.method)
def __del__(self):
super(A, self).__del__()
del self.method
def method(self):
pass
Did you try this?
>
> To decorate a method, you'd best just decorate it normally. I doubt your
> technique will work anyway, as the function returned by the decorator
> isn't bound to the object, you'd need to pass one self reference
> implicitly, which is then thrown away.
Looking at the original post, I had included an extra "self" in the
argument list
def decorator(self, *args, **kwds):
should have been
def decorator(*args, **kwds):
With this correction my method decorates instance methods on objects
successfully although I don't know why the garbage collection isn't working.
>
> simply,
>
> def exc_decor(fn):
> @functools.wraps(fn)
> def wrapper(*args, **keywords):
> try:
> return fn(*args, **keywords):
> except:
> #...
> raise
> return wrapper
>
> class X(...):
> @exc_decor
> def foo(self, arg):
> pass
>
> (if targeting pre-decorator Python, the code would look different of course)
>
> This way, the function itself is decorated, and the function returned by
> the decorator is bound to the object. It'll just work as expected, no
> trickery required.
Thanks for this. I remember having some problems decorating instance
methods in the past which is why I started doing it as in the original
post. Your method seems just fine though.
Thanks,
John.
More information about the Python-list
mailing list