装饰器 函数/类实现方式即参数问题

无参装饰器

  • 函数式
def outer(func):
    print('函数outer')
    def inner(*args, **kwargs):
        print('函数inner')
        return func(*args, **kwargs)
    return inner

@outer
def work(a,b):
    print('函数work')
    print('参数是:\t',a,'\t',b)
    return a+b
print()
print('work(1,5)' , work(1,5))

结果:
函数outer

函数inner
函数work
参数是:     1   5
work(1,5) 6

执行顺序:

outer(work)(1,5)
work = outer(work) 即 work 指向inner, 参数func指向原work

  • 类式
class Outer:
    def __init__(self, func):
        print('函数__init__')
        self.func = func

    def __call__(self, *args, **kwargs):
        print('函数__call__')
        return self.func(*args, **kwargs)

@Outer
def work(a,b):
    print('函数work')
    print('参数是:\t',a,'\t',b)
    return a+b
print()
print('work(1,5)' , work(1,5))

结果:
函数__init__

函数__call__
函数work
参数是:     1   5
work(1,5) 6

执行顺序:

outer(work)(1,5)
work = Outer(work) work指向Outer的实例化对象,对象的func属性指向work

有参装饰器

  • 函数式
def outer(param):
    def middle(func):
        print('param:',param)
        def inner(*args, **kwargs):
            return func(*args, **kwargs)
        return inner
    return middle

@outer(5)
def work():
    print('work')

work()
输出:
param: 5
work

执行顺序

outer(5)(work)()

  • 类式
class Outer:
    class Inner:
        def __init__(self, func):
            self.func = func

        def __call__(self, *args, **kwargs):
            print('param', self.param)
            return self.func(*args, **kwargs)
    
    def __init__(self, param):
        self.param = param

    def __call__(self, *args, **kwargs):
        inner = self.Inner(*args, **kwargs)
        inner.param = self.param
        return inner

@Outer(5)
def work():
    print('work')

work()

输出:
param 5
work

执行顺序

Outer(5)(work)()
@Outer(5) Outer(5)执行之后的结果要是一个可执行的函数,
类有 __call__() 方法可以Outer(5)(work)

def outer(param):
    def middle1(param):
        def middle2(func):
            def inner(*args, **kwargs):
                print(param)
                func(*args, **kwargs)
            return inner
        return middle2
    return middle1

#@outer(6)(5) 不支持
def work():
    print('work')

# 这样写是可以的
work = outer(6)(5)(work)
work()

输出:
5
work
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容