装饰器(Decorator)是Python中一个非常强大且常用的功能,它允许你在不修改原有函数或类代码的情况下,给函数或类增加新的功能。装饰器本质上是一个函数,它接收一个函数作为参数并返回一个新的函数。这个新函数是对原函数的一个增强版本,它可以在调用原函数之前或之后执行一些操作。
装饰器的基本使用
定义一个装饰器
装饰器函数通常接受一个函数作为参数,并返回一个新的函数。下面是一个简单的装饰器示例,它会在被装饰的函数执行前后打印日志:
def my_decorator(func): | |
def wrapper(): | |
print("Something is happening before the function is called.") | |
func() | |
print("Something is happening after the function is called.") | |
return wrapper | |
@my_decorator | |
def say_hello(): | |
print("Hello!") | |
say_hello() |
输出将会是:
Something is happening before the function is called. | |
Hello! | |
Something is happening after the function is called. |
使用functools.wraps
在上面的例子中,虽然装饰器工作正常,但如果你尝试获取say_hello
函数的__name__
或__doc__
等属性,你会发现它们现在指向的是wrapper
函数而不是say_hello
函数。为了解决这个问题,可以使用functools.wraps
装饰器来更新wrapper
函数,使其看起来更像被装饰的函数。
from functools import wraps | |
def my_decorator(func): | |
@wraps(func) | |
def wrapper(): | |
print("Something is happening before the function is called.") | |
func() | |
print("Something is happening after the function is called.") | |
return wrapper | |
@my_decorator | |
def say_hello(): | |
"""This function says hello.""" | |
print("Hello!") | |
print(say_hello.__name__) # 输出: say_hello | |
print(say_hello.__doc__) # 输出: This function says hello. |
装饰器带参数
如果你的函数需要参数,你可以通过*args
和**kwargs
来让wrapper
函数接受任意数量的位置参数和关键字参数,并将它们传递给原函数。
def my_decorator(func): | |
@wraps(func) | |
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 | |
@my_decorator | |
def add(a, b): | |
return a + b | |
print(add(5, 3)) |
输出将会是:
Something is happening before the function is called. | |
8 | |
Something is happening after the function is called. |
装饰器是Python中一个非常灵活和强大的特性,它允许你以非侵入式的方式扩展函数或类的功能。