I am trying to implement a decorator class which would decorate methods in other classes. However, I need the class which holds the decorated method available in the decorator. I can't seem to find it anywhere.
Here's an example:
class my_decorator(object):
def __init__(self, arg1, arg2):
print(self.__class__.__name__ + ".__init__")
self.arg1 = arg1
self.arg2 = arg2
def __call__(self, my_callable):
print(self.__class__.__name__ + ".__call__")
print(type(my_callable))
self.my_callable = my_callable
# self.my_callable_method_class = ?where to get this?
def function_wrapper(*args, **kwargs):
print(self.__class__.__name__ + ".function_wrapper")
print(self.arg1)
self.my_callable.__call__(*args, **kwargs)
print(self.arg2)
return function_wrapper
class MyClass(object):
@my_decorator(arg1="one", arg2="two")
def decorated_method(self):
print(self.__class__.__name__ + ".decorated_method")
print(type(self.decorated_method))
print("hello")
m = MyClass()
m.decorated_method()
That will print out this:
my_decorator.__init__
my_decorator.__call__
<type 'function'>
my_decorator.function_wrapper
one
MyClass.decorated_method
<type 'instancemethod'>
hello
two
In the decorator class the callable is of type function, while inside the class itself it is of type instancemethod. I can get the im_class from instancemethod, but there is no such thing in function.
How can I get the class containing the decorated method from within the decorator?
I could do this:
class my_decorator(object):
def __init__(self, cls, arg1, arg2):
.
.
class MyClass(object):
@my_decorator(cls=MyClass, arg1="one", arg2="two")
def decorated_method(self):
.
.
But I would not like to do that because it's redundant and not nice.
Or should I implement this some other way? I basicly need a couple of arguments to the decorator, and I need the class of the decorated method in the decorator.
You could decorate the class:
@decorate
class MyClass(object):
@my_decorator(arg1="one", arg2="two")
def decorated_method(self):
and use the outer decorator to send the class argument to the inner.
None of your proposals can work, because they require access to the class before it exists. When you define a class, you first execute the code inside its body (defining functions etc) and then assign the resulting scope to the class as its __dict__
. So at the time that decorated_method
is defined, MyClass
doesn't exist yet.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With