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.

--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to