Python 一文弄懂Python装饰器
时间: 2025-05-16 15:49:03 浏览: 27
### Python装饰器的概念
Python装饰器是一种特殊类型的函数,用于修改其他函数的行为而不改变其源代码。这种设计模式允许开发者在不更改原始逻辑的情况下增强或扩展函数的功能[^1]。
装饰器本质上是一个接受函数作为参数并返回新函数的高阶函数。通过这种方式,可以在目标函数执行前后添加额外的操作,从而实现诸如日志记录、性能监控或其他横切关注点的功能[^4]。
---
### 装饰器的基本结构
以下是装饰器的一个基本例子:
```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()
```
上述代码展示了如何定义和使用一个简单的装饰器 `my_decorator` 来包裹 `say_hello()` 函数。运行此代码会输出如下内容:
```
Something is happening before the function is called.
Hello!
Something is happening after the function is called.
```
---
### 带有参数的装饰器
如果被装饰的函数需要传递参数,则装饰器内部的嵌套函数也需要支持这些参数。下面的例子展示了一个带有参数的装饰器:
```python
def do_twice(func):
def wrapper_do_twice(*args, **kwargs):
func(*args, **kwargs)
func(*args, **kwargs)
return wrapper_do_twice
@do_twice
def greet(name):
print(f"Hello {name}")
greet("Alice")
```
这段代码将两次调用 `greet("Alice")` 方法,并打印两遍问候语[^2]。
---
### 使用内置装饰器
Python 提供了一些常用的内置装饰器来简化特定场景下的开发工作。例如:
- `@classmethod`: 将方法转换为类方法。
- `@staticmethod`: 定义静态方法。
- `@property`: 把类的方法当作属性访问。
- `@functools.wraps`: 保留原函数元数据(如名称和文档字符串)[^3]。
#### 示例:`@property` 的使用
```python
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def area(self):
return 3.14 * (self._radius ** 2)
c = Circle(5)
print(c.area) # 输出圆的面积
```
在这个例子中,我们利用 `@property` 将 `area` 方法伪装成属性,使得可以通过对象直接访问计算后的值。
---
### 类装饰器
除了函数装饰器外,还可以创建类装饰器以更复杂的方式管理状态或者行为。例如,以下代码片段演示了如何使用类装饰器统计某个函数的调用次数:
```python
import functools
class CallCounter:
def __init__(self, func):
functools.update_wrapper(self, func)
self.func = func
self.calls = 0
def __call__(self, *args, **kwargs):
self.calls += 1
result = self.func(*args, **kwargs)
print(f"{self.func.__name__} has been called {self.calls} times.")
return result
@CallCounter
def add(a, b):
return a + b
add(1, 2)
add(3, 4)
```
每次调用 `add` 函数时都会更新计数器并将当前调用次数打印出来。
---
### 总结
装饰器是Python编程中的一个重要工具,能够帮助程序员编写更加模块化、可重用以及易于维护的代码。无论是基础的日志记录还是复杂的跨领域需求处理,都可以借助于这一强大的特性得以解决。
---
阅读全文
相关推荐










