头歌python函数包装器的使用
时间: 2025-04-28 22:18:01 浏览: 11
### Python 函数装饰器使用教程
#### 理解装饰器的概念
装饰器本质上是一个接受函数作为参数并返回一个新的或修改过的函数的对象。通过这种方式,可以在不改变原始函数代码的情况下增加功能[^1]。
#### 创建简单的装饰器
最基础的形式如下所示:
```python
def simple_decorator(function):
def wrapper():
print("Before the function call.")
function()
print("After the function call.")
return wrapper
```
当应用此装饰器时,任何被其包裹的方法都会在其执行前后打印消息[^2]。
#### 应用装饰器
可以利用`@decorator_name`语法糖来简化装饰器的应用过程。例如,在定义一个名为`greet`的函数之前加上`@simple_decorator`标签,则每次调用`greet()`实际上是在调用了经过装饰后的版本。
```python
@simple_decorator
def greet():
print("Hello!")
greet()
```
这将依次输出:“Before the function call.”、“Hello!”以及“After the function call.”
#### 参数传递给装饰器内部函数
为了使装饰器能够处理带有参数的目标函数,需调整装饰器内的wrapper函数签名以便接收不定数量的位置参数和关键字参数(`*args, **kwargs`)。这样就能灵活应对不同类型的输入了[^3]。
```python
def decorator_with_args(func):
def inner(*args, **kwargs):
print(f"Calling {func.__name__} with arguments: {args}, {kwargs}")
return func(*args, **kwargs)
return inner
@decorator_with_args
def say_hello(name="World"):
print(f"Hello, {name}")
say_hello("Alice") # Calling say_hello with arguments: ('Alice',), {}
# Hello, Alice
```
#### 解决元数据丢失问题
默认情况下,一旦函数被装饰,一些重要的属性如名称、文档字符串等可能会丢失。为了避免这种情况的发生,应该引入来自标准库模块`functools`中的工具——即`wraps`辅助函数。该方法允许复制原始对象的关键特性至新的代理上[^4]。
```python
from functools import wraps
def preserve_metadata(decorator_func):
@wraps(decorator_func)
def decorated(*args, **kwargs):
print("Preserving metadata...")
return decorator_func(*args, **kwargs)
return decorated
@preserve_metadata
def example_function(x):
"""This is an example."""
pass
print(example_function.__doc__) # This is an example.
```
#### 带有可配置选项的高级装饰器
有时可能希望创建具有额外行为控制能力的更复杂的装饰器;这时可以通过闭包机制实现这一点。具体来说就是先构建一层外部作用域用于保存所需设置项,再由内层实际负责逻辑运算的部分访问这些设定值。
```python
import time
def timing(enabled=True):
def actual_decorator(fn):
@wraps(fn)
def timed_call(*args, **kwargs):
start_time = time.time()
try:
result = fn(*args, **kwargs)
finally:
elapsed = time.time() - start_time
if enabled:
print(f"{fn.__name__}: took {elapsed:.6f}s")
return result
return timed_call
return actual_decorator
@timing(False) # 可以传入False关闭计时功能
def slow_operation(n=10_000_000):
sum(range(n))
slow_operation()
```
阅读全文
相关推荐

















