Decorators on Python AbstractMethods
Use __init_subclass__
to apply the timer decorator for you. (timer
, by the way, doesn't need to be defined in the class; it's more general than that.) __init_subclass__
is also a more appropriate place to determine if apply
is callable.
import abc
import functools
import time
def timer(func):
@functools.wraps(func)
def wrapper_timer(*args, **kwargs):
start_time = time.perf_counter()
value = func(*args, **kwargs)
end_time = time.perf_counter()
run_time = end_time - start_time
print(f"Finished {func.__name__!r} in {run_time:.4f} secs")
return value
return wrapper_timer
class Test(metaclass=abc.ABCMeta):
def __init_subclass__(cls, **kwargs):
super().__init_subclass__(**kwargs)
# ABCMeta doesn't let us get this far if cls.apply isn't defined
if not callable(cls.apply):
raise TypeError("apply not callable")
cls.apply = timer(cls.apply)
@abc.abstractmethod
def apply(self, a: str) -> str:
raise NotImplementedError
class T2(Test):
def apply(self, a: str) -> str:
return a
if __name__ == '__main__':
t = T2()
t.apply('a')