python 装饰器使用

# 装饰器:函数作为装饰器参数,在导入模块时候执行装饰器函数


# 函数装饰器
if 0:
    def register(func):
        return func

    @register
    def test1(name, age):
        print(name, age)
        
    @register
    def test2(*args, **kwargs):
        print(args, kwargs)
    
    test1("zhangsan", 10)
        
    test2("a", "b", name="zhangsan", age=20)
    
# 有时候需要对函数做额外的操作,这就需要用到函数闭包    
if 1:
    def register(func):
        # 装饰器中有定义一个函数并返回,可以做其他动作
        def decorator(*args, **kwargs):
            print("begin", func.__name__)
            func(*args, **kwargs)
            print("end", func.__name__)
        return decorator

    @register
    def test1(name, age):
        print(name, age)
        
    @register
    def test2(*args, **kwargs):
        print(args, kwargs)
    
    test1("zhangsan", 20)
        
    test2("a", "b", name="zhangsan", age=20)
    
# 若装饰器函数需要传入参数,用于不同逻辑处理呢,再包裹一层
if 1:
    def register(num):
        # _register做为函数对象返回
        def _register(func):
            def decorator(*args, **kwargs):
                if num:
                    print("begin", func.__name__)
                    func(*args, **kwargs)
                    print("end", func.__name__)
            return decorator
        return _register

    @register(0)
    def test1(name, age):
        print(name, age)
        
    @register(1)
    def test2(*args, **kwargs):
        print(args, kwargs)
    
    test1("zhangsan", 20)
        
    test2("a", "b", name="zhangsan", age=20)
    
if 0:
    # 函数装饰器装饰类,可以为类添加些类属性
    def decorator(cls):
        cls.name = "10"
        return cls

    @decorator
    class Test:
        def test(self):
            print(f"{self.test.__func__}")
            
    
    t = Test() # 相当于 t = decorator(Test)
    
    print(t.name) 
    # 10


if 0:
    # 函数装饰器装饰类,传入参数,参数可以作为类属性
    def decorator(func):
        def wrapper(cls):
            func("exec func")
            cls.name = "10"
            cls.func = func
            return cls
        return wrapper

    def test_print(*arg):
        print(arg)
        
    @decorator(test_print) # 类装饰器传参数
    class Test:
        def test(self):
            print("exec test")
            self.func("exec func in test")
            
    t = Test()
    # ('exec func',)

    print(t.name)
    # 10
    Test.func("use Test class exec func")
    # ('use Test class exec func',)
    t.func("use Test instance exec func")
    # (<__main__.Test object at 0x0000029098443C70>, 'use Test instance exec func'), 打印两个是因为第一个参数有实例self

    t.test()
    # exec test
    # (<__main__.Test object at 0x0000029098443C70>, 'exec func in test'), 第一个参数是self

if 0:
    # 函数装饰器用于装饰类的成员方法
    def register(func):
        return func
    
    # 函数装饰器装饰类成员方法,该方法带有参数
    def register_with_arg(func):
        def decorator(*arg, **kwargs):
            func(*arg, **kwargs)
        return decorator
    
    class Test:
        
        @register
        def test(self):
            print("exec test")
        
        @register_with_arg
        def test_with_arg(self, *arg, **kwargs):
            print("exec test_with_arg")
            
    t = Test()
    t.test()
    # exec test

    t.test_with_arg()
    # exec test_with_arg
    
if 1:
    # 静态方法和类方法作为函数装饰器,可以装饰外部函数,外部类和内部类成员函数
    class Test:
        NAME="zhangsan"
        
        # 静态方法作为装饰器函数,用法和普通装饰器函数一样,没有区别
        @staticmethod
        def test_static(func):
            def decorator(*arg, **kwargs):
                func(*arg, **kwargs)
            return decorator
        
        # 类方法作为装饰器函数,可以用类属性
        @classmethod
        def test_class(cls, func):
            def decorator(*arg, **kwargs):
                print(cls.NAME)
                func(*arg, **kwargs)
            return decorator
        
        # 类方法作为装饰器函数装饰类, 第一个cls1是Test类,cls2是被装饰类
        @classmethod
        def test_class_decorator_class(cls1, cls2):
            def decorator(*arg, **kwargs):
                print(cls1.NAME)
                return cls2
            return decorator
        
        @test_static #使用类静态成员方法装饰该类的实例成员方法,不要加上Test,因为该类还没有定义完,所以会报undefined
        def test_method(self, *arg, **kwargs):
            print(arg, kwargs)
            
            
    @Test.test_static
    def external_static_func(*arg, **kwargs):
        print(arg, kwargs)

    @Test.test_class
    def external_class_func(*arg, **kwargs):
        print(arg, kwargs)
    
    
    @Test.test_class_decorator_class
    class MyTest:
        def test():
            print("exec MyTest.test")
            
    external_static_func("hello", "world")
    # ('hello', 'world') {}

    external_class_func("hello", "zhangsan")
    # zhangsan
    # ('hello', 'zhangsan') {}
    
    t = MyTest()
    t.test()
    # zhangsan
    # exec MyTest.test
    ts = Test()
    ts.test_method("lisi")
    # ('lisi',) {}
    ts.test_method1("wangwu")
    # ('wangwu',) {}

    
if 1:
    # 类作为装饰器
    class Test:pass

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值