Beim rumspielen mit Decorators ist mir gestern aufgefallen, dass es anscheinend nicht so einfach ist, Klassenmethoden mit Decorator classes zu dekorieren. Beispiel:
Code: Alles auswählen
from functools import wraps
def f_decorate(func):
@wraps(func)
def wrapper(*args, **kwargs):
print(f"{func=}")
print(f"{args=}")
print(f"{kwargs=}")
return func(*args, **kwargs)
return wrapper
class c_decorate:
def __init__(self, func):
self._func = func
def __call__(self, *args, **kwargs):
print(f"{self._func=}")
print(f"{args=}")
print(f"{kwargs=}")
return self._func(*args, **kwargs)
@f_decorate
def f_add(a, b):
print("this is a function decorated with a function")
print(f"{a} + {b} = {a+b}")
return a + b
@c_decorate
def c_add(a, b):
print("this is a function decorated with a class")
print(f"{a} + {b} = {a+b}")
return a + b
class Dings:
@f_decorate
def f_add(self, a, b):
print("this is a method decorated with a function")
print(f"{a} + {b} = {a+b}")
return a + b
@c_decorate
def c_add(self, a, b):
print("this is a method decorated with a class")
print(f"{a} + {b} = {a+b}")
return a + b
def main():
print("--------Functions--------------------")
f_add(1, 2)
print("-------------------------------------")
c_add(1, 2)
print("=====================================")
print("--------Methods----------------------")
d = Dings()
d.f_add(1, 2)
print("-------------------------------------")
d.c_add(1, 2)
if __name__ == "__main__":
main()
Code: Alles auswählen
$ python --version
Python 3.13.7
$ python decorator_example.py
--------Functions--------------------
func=<function f_add at 0x7e693dd8f6a0>
args=(1, 2)
kwargs={}
this is a function decorated with a function
1 + 2 = 3
-------------------------------------
self._func=<function c_add at 0x7e693ddebba0>
args=(1, 2)
kwargs={}
this is a function decorated with a class
1 + 2 = 3
=====================================
--------Methods----------------------
func=<function Dings.f_add at 0x7e693ddebce0>
args=(<__main__.Dings object at 0x7e693ef37a10>, 1, 2)
kwargs={}
this is a method decorated with a function
1 + 2 = 3
-------------------------------------
self._func=<function Dings.c_add at 0x7e693ddebe20>
args=(1, 2)
kwargs={}
Traceback (most recent call last):
File "/home/skirnir/dabble/decorator_example.py", line 61, in <module>
main()
~~~~^^
File "/home/skirnir/dabble/decorator_example.py", line 58, in main
d.c_add(1, 2)
~~~~~~~^^^^^^
File "/home/skirnir/dabble/decorator_example.py", line 21, in __call__
return self._func(*args, **kwargs)
~~~~~~~~~~^^^^^^^^^^^^^^^^^
TypeError: Dings.c_add() missing 1 required positional argument: 'b'