装饰器
装饰器本身是一种设计模式,Python中则基于这种设计模式提供了装饰器语法糖,它能在不改变函数本身的情况下扩展或增强函数的功能。装饰器本质上是一个高阶函数,它接受一个函数作为参数,并返回一个具有增强功能的新函数。
定义和使用装饰器
下面例子代码我们定义了一个装饰器@log
,它在函数执行前和执行后分别打印一些信息。
from typing import Callable
def log(func: Callable) -> Callable:
def wrapper(*args, **kwargs):
print("Something is happening before the function is called.")
result = func(*args, **kwargs)
print("Something is happening after the function is called.")
return result
return wrapper
@log
def say_hello():
print("Hello!")
@log
def bark(loop: int):
for i in range(loop):
print("bark!")
say_hello()
bark(3)
代码中装饰器的内部实际上定义了一个新的函数wrapper
,它接收任意参数并将参数原样传给被装饰的func
函数,wrapper
函数内在调用func
函数前后打印了一些信息,然后将func
的返回值原样返回。
注意:上面代码中我们的装饰器@log
还处理了参数和返回值,这使得它能够装饰任意函数,这让我们编写的装饰器更具通用性,这也是一种最佳实践。
带参数装饰器
Python的装饰器也可以是带有参数的,此时我们可以用一个三阶函数来实现带参数装饰器,下面是一个例子。
from typing import Callable
def repeat(times: int) -> Callable:
def decorator(func: Callable) -> Callable:
def wrapper(*args, **kwargs):
for _ in range(times):
func(*args, **kwargs)
return wrapper
return decorator
@repeat(3)
def say_hello():
print("Hello, world!")
say_hello()
代码中我们自定义了@repeat
装饰器,它可以将内部的函数重复执行若干次,我们可以发现它实际上还是一个闭包。
装饰器函数内部返回一个接收func
参数的函数,该函数内部又返回一个接收任意参数的wrapper
函数,wrapper
函数内部重复执行被装饰的func
函数。这里我们就没有处理被装饰函数的返回值了,因为它被多次调用,所以返回值没有太大意义,实际开发中我们可以根据实际情况来决定是否处理返回值。
作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。