This is a base Python question. I am trying to decorate a @classmethod
with my own decorator, my_decorator
. The original @classmethod
actually calls another @classmethod
inside. The problem comes up when calling this inner method because it depends on the cls
argument. This would be fine if I could just replace any call like cls.boo()
with Foo.boo()
if my class is always Foo
, but this is obviously not a choice when I write children classes that inherit from Foo
. Below is what I am trying to write.
def my_decorator(method):
def redefined_method(*args, **kwargs):
print('Starting decorator')
result = method(args, **kwargs)
return result
return redefined_method
class Foo(object):
@classmethod
def boo(cls):
print('Running from Foo\'s boo')
@classmethod
@my_decorator
def bar(cls):
print('Running from Foo\'s bar')
'''
Replacing the following line with 'Foo.boo()'
produces no errors when calling `Foo.bar()`,
but then we can't run Child's version of the boo method.
'''
cls.boo()
class Child(Foo):
@classmethod
def boo(cls):
print('Running from Child\'s version of boo')
if __name__ == '__main__':
Foo.bar()
Child.bar()
I expect the following output.
Starting decorator
Running from Foo's bar
Running from Foo\'s boo
Starting decorator
Running from Foo's bar
Running from Child\'s version of boo
Current output.
Starting decorator
Running from Foo's bar
Traceback (most recent call last):
File "C:\....\dec_example.py", line 29, in <module>
Foo.bar()
File "C:\....\dec_example.py", line 4, in redefined_method
method(args, **kwargs)
File "C:\....\dec_example.py", line 21, in bar
cls.boo()
AttributeError: 'tuple' object has no attribute 'boo'
I tried switching the order of @classmethod
and @my_decorator
but it still doesn't work and produces the following stacktrace.
Starting decorator
Traceback (most recent call last):
File "C:\....\dec_example.py", line 29, in <module>
Foo.bar()
File "C:\....\dec_example.py", line 4, in redefined_method
method(args, **kwargs)
TypeError: 'classmethod' object is not callable
You forgot to unpack args
:
def my_decorator(method):
def redefined_method(*args, **kwargs):
print('Starting decorator')
method(args, **kwargs)
# here ^, no star!
return redefined_method
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.