装饰器
装饰器是一个以函数作为参数并返回一个替换函数的可执行函数。简单来说就是装饰原有的函数。
下面代码中的apply函数形参为函数func、变量x、y(在Python中,函数和其他任何东西一样,都是对象,这意味着可以将函数当做实参传递给函数,或者在函数中将函数作为返回值返回),apply函数相当于对func函数进行装饰,但还达不到装饰器的程度。
1.py
>>> def add(x, y):
... return x + y
>>> def sub(x, y):
... return x - y
>>> def apply(func, x, y): # 1
... return func(x, y) # 2
>>> apply(add, 2, 1) # 3
3
>>> apply(sub, 2, 1)
1
下面是一个简单装饰器的代码:
2.py
>>> def outer(some_func):
... def inner():
... print "before some_func"
... ret = some_func() #1
... return ret + 1
... return inner
>>> def foo():
... return 1
>>> decorated = outer(foo) # 2
>>> decorated()
before some_func
2
在这个装饰器示例中,首先,定义了一个带单个参数 some_func
的名为 outer
的函数。然后在 outer
内部定义了一个内嵌函数 inner
。inner
函数将打印一行字符串然后调用 some_func
,并在 #1
处获取其返回值。在每次 outer
被调用时,some_func
的值可能都会不同,但不论 some_func
是什么函数,都将调用它。最后,inner
返回 some_func()
的返回值加 1。在 #2
处可以看到,当调用赋值给 decorated
的返回函数时,得到的是一行文本输出和返回值 2,而并不是调用的 foo
函数的返回值 1。
函数装饰器@符号的使用
Python 通过在函数定义前添加一个装饰器名和 @ 符号,来实现对函数的包装。
而使用装饰器只需要在函数前添加 @装饰器名 即可。
3.py
>>> def outer(some_func):
... def inner():
... print "before some_func"
... ret = some_func() #1
... return ret + 1
... return inner
>>> @ outer
>>> def foo():
... return 1
>>> foo()
before some_func
2
上述代码是使用@符号对2.py的改写,这种方式和简单的使用 outer 函数的返回值来替换原始变量的做法没有什么不同—— Python 只是添加了一些语法糖来使之看起来更加明确。
上述内容参考:简单 12 步理解 Python 装饰器