I have a function, a class implementing the similar method and a decorator. The current decorator signature does allow it to be used for the function but doesn't work with the method as expected.
from functools import wraps
def nice(f):
@wraps(f)
def decorator(a, b):
result = f(a, b)
return 'result is: %s' % str(result)
return decorator
@nice
def sumup(a, b):
return a + b
class Test:
def __init__(self):
pass
@nice
def sumup(self, a, b):
return a + b
print(sumup(2, 6))
cls = Test()
print(cls.sumup(4, 8))
Can I somehow 'overload' decorator? In C++ I would be able to write the same decorator again with the same name but different signature and it would work. Can I use some nice solutions in this case? Or I need to just add the same decorator with different name like:
def nice_cls(f):
@wraps(f)
def decorator(self, a, b):
result = f(self, a, b)
return 'result is: %s' % str(result)
return decorator
and use it for the method?
While I generally agree with @jsbueno 's answer that overloading will require `typing.overload` I'm not sure it is needed for your example.
Sure, regarding the part of your question about "Can I somehow 'overload' decorator?" yes, you can and you would need `typing.overload` (as already mentioned) and you can read more about it in the official PEP-484 (python-enhancement-proposal) specifically the part about overloading: https://peps.python.org/pep-0484/#function-method-overloading
However, decorators are going to behave more like a C++ generic constructor for functions in your example through some syntactic sugar. So, regarding the remaining part of your question: "Can I use some nice solutions in this case?" yes, just make the method static.
The only issue with your example code I see is the class method is not marked as 'static' but implemented as static, yet called on the instance when used.
e.g, more decorators is simple and works in this case
# double decorate static class method to drop the unused self argument
@nice
@staticmethod
def sumup(a, b):
return a + b
This way your @nice
decorator takes the "static" "member" method (e.g., instead of the C++ covariant-like argument) output by the @staticmethod
decorator which takes the static class function as input,
OR (as mentioned already) you could also just move the scope of a
, b
, to the decorator like so:
def nice(f, *args, **kwargs):
@wraps(f)
def decorator(*args, **kwargs):
result = f(*args, **kwargs)
return 'result is: %s' % str(result)
return decorator
from my light testing:
from functools import wraps
def nice(f, *args, **kwargs):
@wraps(f)
def decorator(*args, **kwargs):
result = f(*args, **kwargs)
return 'result is: %s' % str(result)
return decorator
@nice
def sumup(a, b):
return a+ b
# >>> sumup(9, 8)
# 'result is: 17'
# >>>
# >>> class Test:
# ... def __init__(self):
# ... pass
# ...
# ... @nice
# ... def sumup(self, a, b):
# ... return a + b
# ...
# >>> cls = Test()
# ... print(cls.sumup(4, 8))
# ...
# result is: 12
# >>>
sorry for the rushed answer, hopefully this helps.