Reputation: 31
I want to simplify method decoration in situations like delegate class implementations.
That situation leads to something like:
class ServiceDelegate(Service):
@decorator
def service_method1(self):
super().service_method1()
@decorator
def service_method2(self):
super().service_method2()
@decorator
def service_method3(self):
super().service_method3()
...
This solution doesn't seems very productive. For this reason something like this could be implemented:
def methods_decorator(deco, regex: str, base_class=None):
def f(c: type):
nonlocal base_class
# Default base class is the decorated class itself
if not base_class:
base_class = c
avoid_functions: List[str] = ["__init__","__doc__","__module__"]
# regex functions
def lmd(i): return i[0] not in avoid_functions and re.fullmatch(regex, i[0])
funcs = list(filter(lmd, base_class.__dict__.items()))
for func in funcs:
print(str(type(func[1])))
if type(func[1]) == FunctionType:
setattr(c, func[0], deco(func[1]))
elif type(func[1]) == StaticMethodType:
setattr(c, func[0], staticmethod(deco(func[1])))
elif type(func[1]) == ClassMethodType:
setattr(c, func[0], classmethod(deco(func[1])))
return c
return f
@methods_decorator(deco=decorator1, regex="service_method.*", base_class=Service)
@methods_decorator(deco=decorator2, regex="other_method.*", base_class=Service)
@methods_decorator(deco=decorator3, regex="new.*")
class ServiceDelegate(Service):
def new_method(self):
# Some new func here
...
The idea is to "copy" and decorate regex selected functions from the base class without having to override them. This implementation works for me in my specific scenario.
I'm pretty new to python so I'm not really sure if this is a good approach or could be a bad practice.
Upvotes: 1
Views: 207
Reputation: 41
The solution is for typing less. However, it just moves complexities from adding method decorators to naming methods and adding a magic class decorator.
Changing the name of the method decorator and names of methods is a better idea.
class ServiceDelegate(Service):
@service
def method1(self):
super().method1()
@service
def method2(self):
super().method2()
@service
def method3(self):
super().method3()
Omitting the service_
prefix and adding @service
make exactly no change of the amount of typed characters and the magic class decorator is not required anymore.
Upvotes: 2