Python学习之路-----装饰器(5)

装饰器带参数

装饰器本身也是函数,它以闭包的形式存在,且已经存在一个形参(即被修饰的函数)。那么如果装饰器本身在修饰时需要参数才如何写这个装饰器呢?直接看正确代码

#coding=utf-8

def f1_arg(arg):

    print('in f1_arg,arg:%s' % arg)
    def f1(func):
        print('in func,arg:%s' % arg)
        def f1_inner():
            print('in f1_inner')
            func()
        return f1_inner

    return f1

#装饰器f1_arg修饰f_a时传入的一个字符串yes
@f1_arg('yes')
def f_a():
    print('in f_a')


if __name__ == '__main__':
    f_a()



结果:
in f1_arg,arg:yes
in func,arg:yes
in f1_inner
in f_a

如上面的@f1_arg('yes')就是一个带参数的装饰器,来看一下它的实现部分。发现在f1_arg中定义了一个闭包f1,然后返回了f1,而闭包f1就是之前常用的装饰器的形式。那整个原理是怎样的呢?

  • 先执行f1_arg这个函数,这个函数返回了一个闭包;
  • 只用f1_arg的返回值来修饰f_a;

这就是装饰器自身带参数,在实现上就是原来的闭包实现外侧又定义了一个函数,且函数返回内部的闭包。

带参数的装饰器有什么用

        假设有函数f_a()和f_b(),目前都要拓展功能,但各自的新需求还不一样,那么用一个装饰器能实现吗?可以!

#coding=utf-8

str1 = '需求1'
str2 = '需求2'

def f1_arg(arg):

    print('in f1_arg,arg:%s' % arg)
    def f1(func):
        print('in func,arg:%s' % arg)
        def f1_inner():
            print('in f1_inner')
            if arg == '需求1':
                print('do 需求1')
            elif arg == '需求2':
                print('do 需求2')
            func()
        return f1_inner

    return f1


@f1_arg('需求1')
def f_a():
    print('in f_a')


@f1_arg('需求2')
def f_b():
    print('in f_b')

if __name__ == '__main__':
    f_a()
    print('-' * 10)
    f_b()




结果:
in f1_arg,arg:需求1
in func,arg:需求1
in f1_arg,arg:需求2
in func,arg:需求2
in f1_inner
do 需求1
in f_a
----------
in f1_inner
do 需求2
in f_b
发布了76 篇原创文章 · 获赞 21 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/shen_chengfeng/article/details/102537477