在前面一文《python里为什么需要使用装饰器(decorator)》里,我们学习了为什么需要装饰器,知道装饰器就是为了不修改原来函数的代码,又达到增加功能的作用。其实为了装饰器更通用化,那么装饰器是否也可以带参数呢?其实是可以的,这样更加通用化了,达到共享极点。在前面也学习《为什么要使用闭包(closures)》一文,知道参数可以嵌套函数里实现隐藏,并且实现全局参数的功能,与函数一起绑定。因此只需要结合这两个知识点,就可以产生通用带参数的装饰器了。原来不带参数的代码如下:
-
-
- def printStar(func):
- def f():
- print('*************************************')
- return func()
- return f
-
- @printStar
- def add():
- return 1 + 1
-
- @printStar
- def sub():
- return 2 -1
-
- print(add())
-
- print(sub())
现在再对装饰器函数进一步修改,再嵌套一层函数,实现闭包的功能,代码就修改如下:
-
-
- def title(show = ''):
- def printStar(func):
- def f():
- print(show,'*************************************')
- return func()
- return f
- return printStar
-
- @title('add')
- def add():
- return 1 + 1
-
- @title('sub')
- def sub():
- return 2 -1
-
- print(add())
-
- print(sub())
输出如下:
add *************************************
2
sub *************************************
1
经过带参数的装饰器的修改,这时控制输出的内容,就更方便了。可以根据不同的函数名称来进行修改输出提示。
前面发现被装饰的函数都没有带参数,这是为了简单起见,现在来学习一下如果被装饰的函数也参数,怎么样修改呢?
可以看下面的代码:
-
-
- def title(show = ''):
- def printStar(func):
- def f(a, b):
- print(show,'*************************************')
- return func(a, b)
- return f
- return printStar
-
- @title('add')
- def add(a, b):
- return a + b
-
- @title('sub')
- def sub(a, b):
- return a - b
-
- print(add(1, 1))
-
- print(sub(2, 1))
由两段代码相比较,可以发现函数传送参数是修改def f(a, b),就是第三层的函数。