I've been looking to make an object-oriented setup to make decorator factories. A simple version can be found in this stackoverflow answer. But I'm not totally satisfied with the simplicity of the interface.
THe kind of interface I envision would use special class Decora
that I can use as such:
class MultResult(Decora):
mult: int = 1
i_am_normal = Literal(True) # will not be included in the __init__
def __call__(self, *args, **kwargs): # code for the wrapped functoin
return super().__call__(*args, **kwargs) * self.mult
That would result in the following behavior:
>>> @MultResult(mult=2)
... def f(x, y=0):
... return x + y
...
>>>
>>> signature(MultResult) # The decorator has a proper signature
<Signature (func=None, *, mult: int = 1)>
>>> signature(f) # The decorated has a proper signature
<Signature (x, y=0)>
>>> f(10)
20
>>>
>>> ff = MultResult(lambda x, y=0: x + y) # default mult=1 works
>>> assert ff(10) == 10
>>>
>>> @MultResult # can also use like this
... def fff(x, y=0):
... return x + y
...
>>> assert fff(10) == 10
>>>
>>> MultResult(any_arg=False) # should refuse that arg!
Traceback (most recent call last):
...
TypeError: TypeError: __new__() got unexpected keyword arguments: {'any_arg'}
See Question&Answers more detail:os