Python 语言进阶 —— 装饰器
介绍
Python 中的装饰器是一种用于修改或增强函数(或方法)功能的设计模式。装饰器本质上是一个返回函数的高阶函数,可以在不修改原有函数代码的情况下,为其添加额外的功能。
装饰器本质上是一个函数,它接收一个函数作为参数并返回一个新的函数。这个新的函数就是对原有函数的一种包装或增强。这样可以使得在不改变原函数代码的前提下,给 原函数额外增加一些功能。
定义步骤
定义一个装饰器的步骤可以分成如下几步:
- 编写装饰器函数。首先,创建一个装饰器函数,该函数将另一个函数作为参数接收。
- 实现包装逻辑。在装饰器函数内部,定义一个包装函数(wrapper)。这个包装函数负责调用传入的原函数,并能够在调用前后插入额外的逻辑。
- 返回包装函数。装饰器函数应返回这个包装函数,以便替代原始函数的行为。
- 应用装饰器。在需要装饰的函数声明前,使用
@
符号并指定装饰器的名称。这样,Python 解释器会自动将目标函数传递给装饰器,并用返回的包装函数替换原函数
# 1. 编写装饰器函数
def decorator_function(original_function):
# 2. 实现包装逻辑
def wrapper_function(*args, **kwargs):
# 在这里可以添加功能
print("Wrapper executed before {}".format(original_function.__name__))
# 调用原函数
result = original_function(*args, **kwargs)
# 在这里可以添加功能
print("Wrapper executed after {}".format(original_function.__name__))
return result
# 3. 返回包装函数
return wrapper_function
# 4. 应用装饰器
@decorator_function
def say_hello(name):
print("Hello, {}".format(name))
# 调用被装饰的函数
say_hello("Alice")
输出:
Wrapper executed before say_hello
Hello, Alice
Wrapper executed after say_hello
带参数的装饰器
当被修饰的函数需要参数时,装饰器中的包装函数可以通过*args
和 **kwargs
接收这些参数。
def decorator(func):
def wrapper(*args, **kwargs):
print("Function is called with arguments:", args, kwargs)
result = func(*args, **kwargs)
return result
return wrapper
@decorator
def my_function(x, y):
return x + y
print(my_function(3, 4))
传递参数给装饰器
如果需要给装饰器本身传递参数,可以使用一个外层函数来封装装饰器。
def repeat(num_times):
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(num_times):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(3)
def say_hello():
print("Hello!")
say_hello() # 输出三次Hello!
保留原信息
在使用装饰器时,原函数的元信息(如函数名、文档字符串等)会被包装函数所替代。为了保留这些信息,可以使用 functools.wraps
装饰器。
from functools import wraps
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 example():
"""This is an example function."""
print("Hello from a function.")
print(example.__doc__) # 输出: This is an example function.