Python学习之路(20)——装饰器
我们知道,对于Python语言而言,有一个很重要的概念——“一切皆对象”。
数字、字符串、元组、列表、字典等所有内置数据类型,以及函数、方法、类、模块等,在Python中所有的一切都是对象。它们都可以赋值给变量,或者可以作为参数传递给函数。
下面一个例子就是将Python中的函数作为参数传递给另一个函数,同事赋值给变量:
>>> def foo1():
print("foo1()")
>>> def foo2(func):
func()
>>> foo2(foo1)
foo1()
>>>
>>> foo3 = foo1
>>> foo3()
foo1()
实际上装饰器(Decorator)本质上是一个Python函数或类,它接收一个函数或类,并返回一个函数/类对象。在装饰器内部,可以让原函数或类在不需要做任何代码修改的前提下增加额外功能,进行“包装”。
比如一个hello代码:
>>> def hello(fn):
def wrapper():
print("hello, %s" % fn.__name__)
fn()
print("goodbye, %s" % fn.__name__)
return wrapper
>>> @hello
def foo():
print("i am foo")
>>> foo()
hello, foo
i am foo
goodbye, foo
可以看到:
1)函数foo定义前有一个@hello,hello就是在前面定义的函数hello
2)在hello函数中,需要一个fn的参数(这个就是用来做回调的函数)
3)hello函数中返回了一个inner函数wrapper,这个wrapper函数回调了传进来的fn,并在回调前后增加两条打印信息
Decorator的本质
对于Python的语法糖(Syntactic Sugar)@而言,当使用一个@decorator来修饰一个函数func时,
@decorator
def func():
pass
其解释器会解释成如下:
func = decorator(func)
这不就是把一个函数当做参数,传递到另一个函数中,然后再回调吗?
是的,但是需要注意到,这里还有一个赋值语句,把decorator这个函数的返回值赋值回原来的func。
由于我们可以把函数当成变量来使用,所以,装饰器decorator必须得返回一个函数出来给func,这就是所谓的高阶函数(higher order function)。
回到hello()这个例子,我们可以看到,hello(foo)返回了wrapper()函数,所以foo其实编程了wrapper的一个变量,而后面的foo()其实编程了wrapper()。
至此,装饰器decorator的概念就基本清楚了吧?
浙公网安备 33010602011771号