python的装饰器
Python 装饰器是一种特殊的函数,它可以接受一个函数作为输入,并返回一个新的函数,用于增强或修改原函数的功能
装饰器在不修改原函数代码的前提下,为函数添加额外的功能,比如日志记录、性能测试、权限验证等
语法
装饰器的语法使用 @
符号,它通常放在被装饰函数的定义之前:
def my_decorator(func):
def wrapper():
print("在函数执行之前做一些事情")
func()
print("在函数执行之后做一些事情")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
my_decorator 是一个装饰器函数,say_hello 是被装饰的函数
@my_decorator
这一行代码相当于执行了 say_hello = my_decorator(say_hello)
原理
装饰器本质上是一个高阶函数,即一个可以接受函数作为参数并返回函数的函数。当使用 @
语法应用装饰器时,Python 会自动将被装饰的函数作为参数传递给装饰器函数,并将装饰器函数返回的新函数赋值给原来的函数名
my_decorator 接受 say_hello 函数作为参数,返回一个新的函数 wrapper
当调用 say_hello() 时,实际上调用的是 wrapper(),在 wrapper 函数内部,会先执行一些额外的操作,然后调用原函数 func()(即 say_hello),最后再执行一些其他操作
处理带参数的函数
如果被装饰的函数带有参数,装饰器中的 wrapper 函数也需要能够接受这些参数。可以使用 *args
和 **kwargs
:
def my_decorator(func):
def wrapper(*args, **kwargs):
print("在函数执行之前做一些事情")
result = func(*args, **kwargs)
print("在函数执行之后做一些事情")
return result
return wrapper
@my_decorator
def add(a, b):
return a + b
result = add(3, 5)
print(result)
wrapper 函数使用 *args
和 **kwargs
来接受任意数量的位置参数和关键字参数,并将它们传递给原函数 func
带参数的装饰器
装饰器本身也可以接受参数。这需要在原有的装饰器基础上再嵌套一层函数:
def repeat(n):
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(n):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(3)
def say_hi():
print("Hi!")
say_hi()
repeat 是一个接受参数 n 的函数,它返回一个装饰器 decorator
decorator 再返回 wrapper 函数,wrapper 函数会重复调用原函数 n 次
应用场景
日志记录:记录函数的调用信息,如调用时间、参数等
性能测试:测量函数的执行时间
权限验证:在函数执行前验证用户的权限
缓存:缓存函数的结果,避免重复计算
总结
Python 装饰器是一种强大而灵活的工具,它可以帮助开发人员编写更加模块化、可复用和易于维护的代码