Python 装饰器:函数的增强与重用367


Python 的装饰器 (Decorator) 是一种强大的语法特性,它允许你以一种简洁优雅的方式,在不修改原函数代码的情况下,为函数添加额外的功能。这就像给函数穿上了一件“装饰”,赋予它新的能力。装饰器广泛应用于日志记录、权限控制、性能监控、缓存等等场景,极大地提升了代码的可读性和可维护性。

本质上,装饰器是一个接受函数作为输入并返回另一个函数的高阶函数。理解装饰器关键在于理解函数作为一等公民的概念:函数可以被赋值给变量,作为参数传递给其他函数,也可以作为函数的返回值。

简单的装饰器示例:

让我们从一个简单的例子开始。假设我们想为一个函数添加日志记录功能,记录函数的执行时间。我们可以使用装饰器来实现:```python
import time
def elapsed_time(func):
def f_wrapper(*args, kwargs):
t_start = ()
result = func(*args, kwargs)
t_elapsed = () - t_start
print(f"Function {func.__name__} took {t_elapsed:.4f} seconds")
return result
return f_wrapper
@elapsed_time
def my_function(n):
(n)
return n * 2
result = my_function(2)
print(f"Result: {result}")
```

在这个例子中,`elapsed_time` 就是一个装饰器。它接受函数 `my_function` 作为输入,返回一个新的函数 `f_wrapper`。`f_wrapper` 在执行 `my_function` 之前记录开始时间,执行之后记录结束时间并计算时间差,最后打印执行时间。 `@elapsed_time` 语法糖等价于 `my_function = elapsed_time(my_function)`。

带有参数的装饰器:

有时候,我们需要为装饰器传递参数。这可以通过嵌套函数来实现:```python
def repeat(num_times):
def decorator_repeat(func):
def wrapper_repeat(*args, kwargs):
for _ in range(num_times):
result = func(*args, kwargs)
return result
return wrapper_repeat
return decorator_repeat
@repeat(num_times=3)
def greet(name):
print(f"Hello, {name}!")
greet("World")
```

在这个例子中,`repeat` 函数接收一个参数 `num_times`,并返回一个装饰器函数 `decorator_repeat`。这个装饰器函数再返回一个包装器函数 `wrapper_repeat`,该函数将被装饰的函数执行 `num_times` 次。

使用 `` 保持元数据:

当使用装饰器时,被装饰函数的元数据(如 `__name__`、`__doc__` 等)可能会丢失。为了避免这种情况,我们可以使用 `` 装饰器:```python
import functools
def my_decorator(func):
@(func)
def wrapper(*args, kwargs):
print("Before function execution")
result = func(*args, kwargs)
print("After function execution")
return result
return wrapper
@my_decorator
def say_hello():
"""This function says hello."""
print("Hello!")
say_hello()
print(say_hello.__name__) # Output: say_hello
print(say_hello.__doc__) # Output: This function says hello.
```

`` 会将原函数的元数据复制到包装器函数中,保证函数的属性不被修改。

类装饰器:

除了函数,我们还可以使用类作为装饰器: ```python
class CountCalls:
def __init__(self, func):
= func
= 0
def __call__(self, *args, kwargs):
+= 1
print(f"Call count: {}")
return (*args, kwargs)
@CountCalls
def my_function():
print("Hello from my_function")
my_function()
my_function()
```

类装饰器通过重载 `__call__` 方法来实现装饰器的功能。

总结:

Python 装饰器是一种强大的工具,它允许我们以简洁的方式扩展函数的功能,提高代码的可重用性和可维护性。 通过学习和掌握装饰器的使用,可以编写更加优雅和高效的 Python 代码。 理解函数作为一等公民的概念,以及装饰器的工作原理,是熟练运用装饰器的关键。

2025-05-29


上一篇:Python高效读取表格数据:方法、库及性能优化

下一篇:Python高危函数及安全编码实践