Python装饰器怎么写_装饰器执行流程详解

9次阅读

装饰器是接收函数为参数并返回新函数的高阶函数,用于不修改原函数代码而增强其行为;支持 @语法糖、带参配置及 functools.wraps 保留元信息。

Python 装饰器怎么写_装饰器执行流程详解

装饰器本质是“函数的函数”

装饰器就是一个接收函数作为参数、返回新函数的可调用对象。它不修改原函数代码,却能增强其行为——比如加日志、计时、权限校验。写法上最常见的是用 @ 语法糖,但底层逻辑始终是:把目标函数传给装饰器,得到一个包装后的新函数。

最简装饰器长这样

先看一个无参装饰器的标准结构:

  def my_decorator(func):
    def wrapper(*args, **kwargs):
      print(“ 调用前执行 ”)
      result = func(*args, **kwargs)
      print(“ 调用后执行 ”)
      return result
    return wrapper

  @my_decorator
  def say_hello():
    print(“Hello!”)

运行 say_hello() 会输出:
调用前执行
Hello!
调用后执行

立即学习Python 免费学习笔记(深入)”;

@语法糖背后发生了什么

这行 @my_decorator 等价于:

say_hello = my_decorator(say_hello)

也就是说:
• Python 在定义 say_hello 后,立刻用它作为参数调用 my_decorator
my_decorator 返回 wrapper 函数
• 原来的 say_hello 名字被重新绑定到 wrapper
• 后续每次调用 say_hello(),实际执行的是 wrapper()

带参数的装饰器要多套一层

如果想让装饰器接收配置(比如日志级别、重试次数),就得再包一层:

  • 最外层函数接收装饰器参数(如 level=”INFO”
  • 中间层才是真正的装饰器,接收被装饰函数
  • 最内层 wrapper 执行逻辑并调用原函数

  def log(level=”INFO”):
    def decorator(func):
      def wrapper(*args, **kwargs):
        print(f”[{level}] 开始执行 {func.__name__}”)
        result = func(*args, **kwargs)
        print(f”[{level}] 执行完成 ”)
        return result
      return wrapper
    return decorator

  @log(“DEBUG”)
  def add(a, b):
    return a + b

此时 @log(“DEBUG”) 先调用 log(“DEBUG”) 得到 decorator,再用它去装饰 add

别忘了保留原函数的元信息

直接写装饰器会导致 say_hello.__name__ 变成 “wrapper”,影响调试和文档生成。解决方法是用 functools.wraps

  from functools import wraps

  def my_decorator(func):
    @wraps(func)  # 这一行关键
    def wrapper(*args, **kwargs):
      return func(*args, **kwargs)
    return wrapper

加上 @wraps(func) 后,wrapper 就会自动复制 func__name____doc____module__ 等属性。

text=ZqhQzanResources