# message

id: msg_0dddd0f4
session_id: session_c4dafe6d
role: assistant
timestamp: 2025-12-15 18:16:30.745867
metadata_json: {}
content:
  # Python装饰器详解

  ## 什么是装饰器？

  装饰器是Python中一种强大的语法特性，它允许在不修改原函数代码的情况下，动态地扩展或修改函数的行为。装饰器本质上是一个**返回函数的高阶函数**。

  ## 核心概念

  ### 1. 装饰器的本质
  装饰器基于以下Python特性：
  - 函数是一等公民（可以作为参数传递和返回）
  - 闭包（函数可以记住并访问其词法作用域中的变量）
  - 语法糖（@decorator语法）

  ### 2. 基本工作原理
  ```python
  # 装饰器函数
  def my_decorator(func):
      def wrapper():
          print("函数执行前")
          func()
          print("函数执行后")
      return wrapper

  # 使用装饰器
  @my_decorator
  def say_hello():
      print("Hello!")

  # 调用被装饰的函数
  say_hello()
  # 输出：
  # 函数执行前
  # Hello!
  # 函数执行后
  ```

  ## 不同类型的装饰器

  ### 1. 函数装饰器（最常用）
  ```python
  # 带参数的函数装饰器
  def repeat(n):
      """重复执行函数n次的装饰器"""
      def decorator(func):
          def wrapper(*args, **kwargs):
              for i in range(n):
                  print(f"第{i+1}次执行:")
                  result = func(*args, **kwargs)
              return result
          return wrapper
      return decorator

  @repeat(3)
  def greet(name):
      print(f"Hello, {name}!")

  greet("Alice")
  ```

  ### 2. 类装饰器
  ```python
  # 类作为装饰器
  class Timer:
      """计时装饰器"""
      def __init__(self, func):
          self.func = func
      
      def __call__(self, *args, **kwargs):
          import time
          start = time.time()
          result = self.func(*args, **kwargs)
          end = time.time()
          print(f"{self.func.__name__} 执行时间: {end-start:.4f}秒")
          return result

  @Timer
  def slow_function():
      import time
      time.sleep(1)
      return "完成"

  slow_function()
  ```

  ### 3. 带参数的类装饰器
  ```python
  class LogLevel:
      """带日志级别的装饰器"""
      def __init__(self, level="INFO"):
          self.level = level
      
      def __call__(self, func):
          def wrapper(*args, **kwargs):
              print(f"[{self.level}] 调用函数: {func.__name__}")
              return func(*args, **kwargs)
          return wrapper

  @LogLevel("DEBUG")
  def debug_function():
      print("调试函数执行")

  debug_function()
  ```

  ## 实用装饰器示例

  ### 1. 缓存装饰器（记忆化）
  ```python
  from functools import lru_cache

  # 使用内置的lru_cache
  @lru_cache(maxsize=128)
  def fibonacci(n):
      if n < 2:
          return n
      return fibonacci(n-1) + fibonacci(n-2)

  # 自定义缓存装饰器
  def memoize(func):
      cache = {}
      def wrapper(*args):
          if args in cache:
              return cache[args]
          result = func(*args)
          cache[args] = result
          return result
      return wrapper

  @memoize
  def factorial(n):
      if n == 0:
          return 1
      return n * factorial(n-1)
  ```

  ### 2. 参数验证装饰器
  ```python
  def validate_args(*types):
      """参数类型验证装饰器"""
      def decorator(func):
          def wrapper(*args, **kwargs):
              # 验证位置参数
              for i, (arg, type_) in enumerate(zip(args, types)):
                  if not isinstance(arg, type_):
                      raise TypeError(f"参数{i}应该是{type_}类型，但得到的是{type(arg)}")
              return func(*args, **kwargs)
          return wrapper
      return decorator

  @validate_args(int, int)
  def add(a, b):
      return a + b

  print(add(5, 3))  # 正常
  # print(add("5", 3))  # 会抛出TypeError
  ```

  ### 3. 重试装饰器
  ```python
  import time
  from functools import wraps

  def retry(max_attempts=3, delay=1):
      """重试装饰器"""
      def decorator(func):
          @wraps(func)
          def wrapper(*args, **kwargs):
              attempts = 0
              while attempts < max_attempts:
                  try:
                      return func(*args, **kwargs)
                  except Exception as e:
                      attempts += 1
                      if attempts == max_attempts:
                          raise
                      print(f"尝试{attempts}失败，{delay}秒后重试... 错误: {e}")
                      time.sleep(delay)
              return None
          return wrapper
      return decorator

  @retry(max_attempts=3, delay=2)
  def unreliable_function():
      import random
      if random.random() < 0.7:
          raise ValueError("随机失败")
      return "成功"
  ```

  ## 使用functools.wraps保持元数据

  ```python
  from functools import wraps

  def my_decorator(func):
      @wraps(func)  # 保持原函数的元数据
      def wrapper(*args, **kwargs):
          """包装函数文档"""
          return func(*args, **kwargs)
      return wrapper

  @my_decorator
  def example():
      """原始函数文档"""
      pass

  print(example.__name__)  # 输出: example（而不是wrapper）
  print(example.__doc__)   # 输出: 原始函数文档
  ```

  ## 多个装饰器的执行顺序

  ```python
  def decorator1(func):
      def wrapper():
          print("装饰器1 - 前")
          func()
          print("装饰器1 - 后")
      return wrapper

  def decorator2(func):
      def wrapper():
          print("装饰器2 - 前")
          func()
          print("装饰器2 - 后")
      return wrapper

  @decorator1
  @decorator2
  def my_function():
      print("原始函数")

  my_function()
  # 输出：
  # 装饰器1 - 前
  # 装饰器2 - 前
  # 原始函数
  # 装饰器2 - 后
  # 装饰器1 - 后
  # 注意：装饰器从下往上执行
  ```

  ## 实际应用场景

  1. **日志记录**：自动记录函数调用信息
  2. **性能测试**：测量函数执行时间
  3. **权限验证**：检查用户权限
  4. **缓存**：存储计算结果
  5. **错误处理**：统一异常处理
  6. **输入验证**：验证函数参数
  7. **事务管理**：数据库事务处理
  8. **路由注册**：Web框架中的路由

  ## 总结

  装饰器是Python中非常强大的工具，它：
  - 遵循开放封闭原则（对扩展开放，对修改封闭）
  - 提高代码复用性
  - 使代码更加简洁和可读
  - 支持AOP（面向切面编程）思想

  掌握装饰器可以让你写出更加优雅和强大的Python代码！


id: msg_94ea6101
session_id: session_c4dafe6d
role: assistant
timestamp: 2025-12-15 18:16:55.790587
metadata_json: {}
content:
  你刚才问的是：**“Python中的装饰器是什么？”**

  这是一个关于Python编程语言核心特性的问题。装饰器（Decorator）是Python中一种强大的语法特性，允许你在不修改原函数代码的情况下，动态地增强或修改函数或类的行为。

  ### 装饰器的核心概念：
  1. **本质**：装饰器本质上是一个**高阶函数**（接受函数作为参数并返回函数）。
  2. **作用**：用于包装另一个函数或类，以添加额外的功能（如日志记录、权限检查、性能测试等）。
  3. **语法**：使用 `@decorator_name` 的语法糖，使代码更简洁。

  ### 简单示例：
  ```python
  # 定义一个装饰器
  def my_decorator(func):
      def wrapper():
          print("函数执行前...")
          func()  # 执行原函数
          print("函数执行后...")
      return wrapper

  # 使用装饰器
  @my_decorator
  def say_hello():
      print("Hello!")

  # 调用函数
  say_hello()
  ```
  **输出：**
  ```
  函数执行前...
  Hello!
  函数执行后...
  ```

  ### 装饰器的工作原理：
  装饰器 `@my_decorator` 相当于执行了：
  ```python
  say_hello = my_decorator(say_hello)
  ```
  它将原函数 `say_hello` 替换为装饰器返回的 `wrapper` 函数。

  ### 带参数的装饰器：
  若需要装饰器接受参数，需嵌套两层函数：
  ```python
  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(num_times=3)
  def greet(name):
      print(f"Hello, {name}!")

  greet("Alice")
  ```
  **输出：**
  ```
  Hello, Alice!
  Hello, Alice!
  Hello, Alice!
  ```

  ### 类装饰器：
  装饰器也可以是类，通过实现 `__call__` 方法：
  ```python
  class CountCalls:
      def __init__(self, func):
          self.func = func
          self.call_count = 0

      def __call__(self, *args, **kwargs):
          self.call_count += 1
          print(f"函数已被调用 {self.call_count} 次")
          return self.func(*args, **kwargs)

  @CountCalls
  def example():
      print("执行函数")

  example()
  example()
  ```
  **输出：**
  ```
  函数已被调用 1 次
  执行函数
  函数已被调用 2 次
  执行函数
  ```

  ### 内置装饰器：
  Python内置了一些装饰器，如：
  - `@staticmethod`：定义静态方法。
  - `@classmethod`：定义类方法。
  - `@property`：将方法转换为属性。

  ### 常见应用场景：
  - **日志记录**：自动记录函数调用信息。
  - **性能测试**：测量函数执行时间。
  - **权限验证**：检查用户权限再执行函数。
  - **缓存结果**：如使用 `@functools.lru_cache` 缓存函数结果。

  ### 注意事项：
  - 使用 `functools.wraps` 保留原函数的元数据（如函数名、文档字符串）：
  ```python
  import functools

  def decorator(func):
      @functools.wraps(func)
      def wrapper(*args, **kwargs):
          return func(*args, **kwargs)
      return wrapper
  ```

  装饰器是Python中实现**AOP（面向切面编程）** 的典型方式，能极大提升代码的可重用性和可读性。


