You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python类方法地址差异、元素类型及代码行为咨询

类方法引用匹配问题解析

先贴出问题中的代码:

class Parent:
    @classmethod
    def func1(cls):
        print("hello func1")

    @classmethod
    def func2(cls):
        print("hello func2")

    @classmethod
    def func3(cls):
        print("hello func3")

    CALCULATE = [func1, func2, func3]
    NO_CALCULATE = []

    @classmethod
    def calculate_kpis(cls):
        for func in cls.CALCULATE:
            if func not in cls.NO_CALCULATE:
                func.__get__(cls)()

class Child(Parent):
    NO_CALCULATE = [Parent.func1]  #REMOVE THIS CALCULATION FROM CHILD

if __name__ == "__main__":
     p1 = Child()
     p1.calculate_kpis()

现象(a):NO_CALCULATE中的func1与Parent类的func1地址不同

当通过Parent.func1访问类方法时,Python会返回一个绑定的类方法对象——这是类方法装饰器生成的包装器,每次访问这个属性,都会生成一个新的绑定实例,内存地址自然不同。而Parent类中CALCULATE列表里的func1,是未绑定的类方法对象(定义时直接引用装饰器返回的原始对象),两者是不同的实例,地址必然不一样。

现象(b):CALCULATE与NO_CALCULATE元素类型不同

  • CALCULATE里的func1/func2/func3:是@classmethod装饰器返回的classmethod类实例,属于未绑定的类方法对象,还没和具体类绑定。
  • NO_CALCULATE里的Parent.func1:通过类属性访问类方法时,Python自动调用classmethod对象的__get__方法,返回的是绑定到Parent类的method对象,和前者不是同一种类型。

整体代码行为

因为CALCULATE的元素是classmethod实例,NO_CALCULATE的元素是绑定后的method实例,两者类型和实例都不匹配,所以func not in cls.NO_CALCULATE的判断永远为True,最终三个函数都会被执行。

修正思路(可选)

如果要实现排除指定类方法的逻辑,可以存储方法的名称字符串替代方法对象,示例如下:

class Parent:
    @classmethod
    def func1(cls):
        print("hello func1")

    @classmethod
    def func2(cls):
        print("hello func2")

    @classmethod
    def func3(cls):
        print("hello func3")

    CALCULATE = [func1, func2, func3]
    NO_CALCULATE = []

    @classmethod
    def calculate_kpis(cls):
        exclude_names = {func.__name__ for func in cls.NO_CALCULATE}
        for func in cls.CALCULATE:
            if func.__name__ not in exclude_names:
                func.__get__(cls)()

class Child(Parent):
    NO_CALCULATE = [Parent.func1]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 08:00:05