You need to enable JavaScript to run this app. Python类实现装饰器的@语法底层转换及结合@classmethod、@staticmethod的实现示例
优惠活动
大模型
产品
解决方案
定价
更多

Python类实现装饰器的@语法底层转换及结合@classmethod、@staticmethod的实现示例

类装饰器@语法的底层转换规则

Python 对所有装饰器(无论装饰器本身是函数还是类)的@语法糖转换规则完全统一,不存在类装饰器专属的转换逻辑。
对应你给出的类装饰器示例:

class decorator_class(object):
    def __init__(self, original_function):
        self.original_function = original_function

    def __call__(self):
        print('call method before {}'.format(self.original_function.__name__))
        self.original_function()

@decorator_class
def display():
    print('display function ran...')

底层完全等价于:

display = decorator_class(display)

逻辑拆解:

  1. 先执行原def display()的定义逻辑,生成原始普通函数对象,临时绑定到变量display
  2. 调用@标记的decorator_class(类本身是可调用对象),传入原始display函数作为唯一参数
  3. decorator_class的__init__接收该函数,生成对应的类实例
  4. 将这个类实例重新赋值给原变量名display
    后续调用display()时,本质是触发该类实例的__call__方法,和装饰器类的设计逻辑完全匹配。
装饰器与@classmethod、@staticmethod的结合用法

@装饰器的执行顺序为从下往上逐层执行,最终的赋值逻辑是将每一层的返回值传给上一层装饰器,最终结果绑定到对应方法名。

先定义一个通用的日志装饰器,支持透传任意位置、关键字参数,方便示例复用:

def log_decorator(func):
    def wrapper(*args, **kwargs):
        print(f"[LOG] 开始执行 {func.__name__}")
        result = func(*args, **kwargs)
        print(f"[LOG] {func.__name__} 执行完成")
        return result
    return wrapper

搭配@classmethod的正确写法

class MyClass:
    @log_decorator
    @classmethod
    def cls_method(cls):
        print(f"这是类方法,当前类为 {cls.__name__}")

底层等价于:

# 1. 先定义原始的类方法函数
def cls_method(cls):
    print(f"这是类方法,当前类为 {cls.__name__}")
# 2. 从下往上逐层执行:先把原始函数转为classmethod描述符
cls_method = classmethod(cls_method)
# 3. 再把classmethod对象传给日志装饰器,得到最终的wrapper函数
cls_method = log_decorator(cls_method)

实际调用输出:

MyClass.cls_method()
# 输出:
# [LOG] 开始执行 cls_method
# 这是类方法,当前类为 MyClass
# [LOG] cls_method 执行完成

顺序说明:如果把两个装饰器的位置反过来,即@classmethod在上、@log_decorator在下,底层会变成cls_method = classmethod(log_decorator(cls_method))。此时log_decorator接收的是未被classmethod包装的原始函数,返回的wrapper会被classmethod统一处理,虽不会报语法错误,但如果你的装饰器需要识别被装饰对象是classmethod类型的描述符,就会拿不到正确的元信息。

搭配@staticmethod的正确写法

执行逻辑与classmethod完全一致,示例:

class MyClass:
    @log_decorator
    @staticmethod
    def static_method(x, y):
        return x + y

底层等价于:

def static_method(x, y):
    return x + y
# 先转成staticmethod描述符
static_method = staticmethod(static_method)
# 再传给装饰器
static_method = log_decorator(static_method)

实际调用输出:

print(MyClass.static_method(3, 5))
# 输出:
# [LOG] 开始执行 static_method
# [LOG] static_method 执行完成
# 8

类装饰器与classmethod的结合示例

你之前实现的类装饰器也可以直接搭配classmethod使用,同样遵循从下往上的执行规则,示例:

class CountCallsDecorator:
    def __init__(self, func):
        self.func = func
        self.call_count = 0
    def __call__(self, *args, **kwargs):
        self.call_count += 1
        print(f"{self.func.__name__} 已被调用 {self.call_count} 次")
        return self.func(*args, **kwargs)

class Demo:
    @CountCallsDecorator
    @classmethod
    def greet(cls):
        print(f"Hello from {cls.__name__}")

实际调用输出:

Demo.greet()
Demo.greet()
# 输出:
# greet 已被调用 1 次
# Hello from Demo
# greet 已被调用 2 次
# Hello from Demo

内容的提问来源于stack exchange,提问作者Parthasarathi Banerjee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.01 11:24:04