Reputation: 3496
I am trying to write a decorator with arguments that wraps methods for a particular class. I've tried both a function and a class decorator and run into different errors. Playing around with arguments for the signatures hasn't helped.
Example usage
class X(object):
def __init__():
self.a = True
self.b = ""
@my_deco([])
def xfunc(self, x, y):
do stuff...
foo = X()
foo.xfunc()
Function decorator:
def my_deco(param1):
def wrapped(func):
def wrapped_f(self, *args, **kwargs):
try:
self.a = True
return func(self, *args, **kwargs)
except Exception as e:
self.b = str(e)
self.a = False
return param1
return wrapped_f
return wrapped
Gives this error: TypeError: wrapped() takes exactly 1 argument (3 given)
Class decorator:
class my_deco(object):
def __init__(self, param1=False):
self.param1 = param1
def __call__(self, f):
@wraps(f)
def wrapped_f(self, *args, **kwargs):
try:
self.a = True
return f(self, *args, **kwargs)
except Exception as e:
self.b = str(e)
self.a = False
return self.param1
return wrapped_f
#
#def __get__(self, obj, objtype):
# """Support instance methods."""
# import functools
# return functools.partial(self.__call__, obj)
Gives this error: TypeError: call() takes exactly 2 arguments (3 given)
Any clues how to get this to work?
Upvotes: 0
Views: 1363
Reputation: 3496
In trying to create runnable code to post as an example, I came across my error. Probably got mixed up at some point in writing the wrapper and trying to get it to work, I overlooked a simple mistake.
Below is the working example. The mistake I made, was I didn't pass a parameter to the decorator for the method I was testing, thus causing the exception. This explains the problem since the decorator was expecting a parameter.
def my_deco(param1):
def wrapped(func):
def wrapped_f(self, *args, **kwargs):
try:
self.a = True
return func(self, *args, **kwargs)
except Exception as e:
self.b = str(e)
self.a = False
return param1
return wrapped_f
return wrapped
class Base(object):
def __init__(self, attr1, attr2):
self.attr1 = attr1
self.attr2 = attr2
self.a = False
self.b = ""
@my_deco([])
def xfunc(self, x, y):
return x + y
def ClassFactory(attr1, attr2, base=Base):
class NewClass(Base):
def __init__(self):
super(NewClass, self).__init__(attr1, attr2)
return NewClass
ChildClass = ClassFactory("foo", "bar")
child = ChildClass()
print child.xfunc(1, 2) # no exception
print child.xfunc('x', 2) # throws exception
Upvotes: 1