Python 装饰器可以对既有方法执行强大的自定义功能, 而且使用
@
关键字已经是很方便的使用方式了,但是无法解决需要装饰所有函数的需求,本文记录解决方案。
需要用到Python类自带的魔法函数
__getattribute__
方法获得方法定义__getattribute__
方法,装饰类中的方法,返回装饰后的函数应该是没有说清楚,上代码吧
from functools import wraps
import time
class Test():
def __init__(self) -> None:
pass
def time_1_sec(self):
time.sleep(1)
def time_2_sec(self):
time.sleep(2)
def time_3_sec(self):
time.sleep(3)
def time_4_sec(self):
time.sleep(4)
def foobar(self):
self.time_1_sec()
self.time_2_sec()
self.time_3_sec()
self.time_4_sec()
def class_timer(input_class):
class MtTimmer(input_class):
def __getattribute__(self, name: str):
func = super().__getattribute__(name)
if str(type(func)) == "<class 'method'>":
is_static_method = False
try :
func_name = func.__name__
except Exception as e:
func_name = func.__func__.__name__
func = func.__func__
is_static_method = True
@wraps(func)
def wrapper(*args, **kwargs):
if is_static_method:
args = args[1:]
start_time = time.time()
res = func(*args, **kwargs)
end_time = time.time()
print('func: {_funcname_} runing: {_time_}s'.format(_funcname_=func_name, _time_=format(end_time - start_time, '.6f')))
return res
return wrapper
return func
return MtTimmer
if __name__ == '__main__':
warpedTest = class_timer(Test)
obj = warpedTest()
obj.foobar()
func: time_1_sec runing: 1.012871s
func: time_2_sec runing: 2.004992s
func: time_3_sec runing: 3.004082s
func: time_4_sec runing: 4.001979s
func: foobar runing: 10.024935s