python
的函数也属于一个对象,可以有一个变量来代替,例如前面说过的一个例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| f=abs print(f(-10)) ```
如果我们在不改变原来函数的前提下,想扩展一个函数的功能。可以重新定义一个函数,把要原函数作为参数传递给`增强函数`,在调用函数前执行一些动作。
```python def revert(a): return abs(a)
def new_func(func): print("do something") return func
f=new_func(revert) print(f(-10))
|
打印结果是:
对于上面的代码,new_func
就是装饰器,可以使用@
对其进行简化:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| def new_func(func): print("do something") return func @new_func def revert(a): return abs(a)
print(revert(-10))
```
这样可以省去一个变量的定义,也维持了原来的方法名称。
上面的装饰器有点过于简单,因为我们只能在`return` 语句前增加内容,想在方法后面增加一个确不行,为了能够实现更强大的装饰器,我们可以对其做修改,再增加一层函数:
``` python def new_func(func): def inner(a): print("do something") res=func(a) print("something is done") return res return inner @new_func def revert(a): print ("processing") return abs(a) print(revert(-10))
|
打印结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| do something processing something is done 10 ```
上面这个装饰器基本满足了我们的需求,但同样还有一个问题,上面的装饰器,只能传递一个参数,所以还是不够一般性。
我们可以使用函数的默认值的方法来解决这个问题,官方给的是`*args 和 **kwargs`(tuple和dict类型),修改如下:
``` python def new_func(func): def inner(*args,**kw): print("do something") res=func(*args,**kw) print("something is done") return res return inner @new_func def revert(a): print ("processing") return abs(a)
print(revert(-10))
|
我们再增加一个方法:
1 2 3 4 5 6
| @new_func def add(x,y): print ("processing") return x+y; print(add(1,2))
|
打印结果是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| do something processing something is done 3 ```
装饰器也可以传递参数,但是需要更深层次的函数:
``` python def new_func(text): print ("call method:",text) def wapper(func): def inner(*args,**kw): print("do something") res=func(*args,**kw) print("something is done") return res return inner return wapper
@new_func("revert") def revert(a): print ("processing") return abs(a) print(revert(-10))
|
运行结果:
1 2 3 4 5
| call method: revert do something processing something is done 10
|