天天看點

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