Python 以类作为装饰器 几种使用场景

发布时间 2023-12-16 12:58:05作者: 爱吃砂糖橘的白龙

1. 原函数、装饰器 都 没有参数

代码:

class Test:
    def __init__(self, func):
        print('Be in __init__ process...')
        self.__func = func
    
    def __call__(self):
        print("...Start decorate...")
        self.__func()
        print("...After decorate...")

@Test  
def func1():     # 相当于 func1 = Test(func) ,先新建一个Test对象,执行__init__方法,保存原始func1函数引用到对象  
    print("this is a func1")

# 现在func1指向一个Test对象
func1()  # Test.__call__

2. 原函数 没有参数 、装饰器 有参数

代码:

class Test2:
    def __init__(self, num):
        print('__init__')
        self.__num = num
    
    def __call__(self, f):
        print(f"__call__ , num = {self.__num}")
        self.__func = f
        return self.old_func        

    def old_func(self):
        print("...Start decorate...")
        self.__func()
        print("...After decorate...")

# Test2(123)的返回值(一个实例对象)对func2进行装饰
@Test2(123)  # obj = Test2(123) 、func2 = obj(func2)  后者会执行__call__函数,现在func2指向一个Test2对象中的old_func引用
def func2():
    print("this is a func2")

func2() 


如果注释掉上面代码最后一行,会有如下输出:

3. 原函数 有参数 、装饰器 没有参数

代码:

class Test3:
    def __init__(self, f):
        print("__init__")
        self.__func = f
    
    def __call__(self, *args, **kwargs):
        print("__call__")
        print("Start decorating")
        self.__func(*args, **kwargs)
        print("After decorating")
@Test3
def func3(name):
    print(f"this is a {name}")

func3("詹姆斯")

4. 原函数 、装饰器 都有参数

class Test4:
    def __init__(self, LEVEL):
        print('In __init__')
        self.__LEVEL = LEVEL
    
    def __call__(self, f):
        print(f"In __call__ , LEVEL = {self.__LEVEL}")
        def wrapper(*args, **kwargs):
            print("...Start decorate...")
            return f(*args, **kwargs)
        return wrapper


@Test4(LEVEL = 'Warning')
def func4(name):
    print(f"this is a {name}")

func4("wybbb")