天天看点

Python 装饰类中所有自定义函数

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           

复制

参考资料

  • https://blog.csdn.net/weixin_36179862/article/details/102829018