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

如何在Python单继承层级中定位方法的定义类?

如何在Python单继承层级中定位方法的定义类?

嘿,这个问题我太熟了!刚好之前做元编程相关需求时折腾过类似场景,咱们一步步来拆解解决它。

首先明确你的核心需求:在单继承的类层级里,不用调用方法的前提下,找到某个方法实际被定义的类——比如你举的例子里,E().f()实际调用的是D类里的f,你想通过get_defining_class(E, 'f')直接拿到D。

先给你吃个定心丸:你提到的遍历__mro__搜索的思路完全可行,而且这正是Python本身查找方法的逻辑,精准度拉满!

具体实现思路

Python的每个类都有__mro__属性,它是一个元组,按照「从最具体的子类到最抽象的父类」的顺序排列了整个继承链(比如你的例子里E.__mro__就是(E, D, C, object))。我们要做的就是顺着这个顺序找第一个自己定义了目标方法的类——这里必须强调「自己定义」,因为如果只是用hasattr检查,会把父类继承来的方法也当成当前类的,导致拿到错误的结果。而'f' in cls.__dict__可以准确判断方法是不是当前类自己定义的(继承来的属性不会出现在子类的__dict__里,除非被覆盖)。

代码示例

先补全你原代码里的小问题(实例方法需要加self参数,不然实例调用会报错):

class C:
    def f(self): pass

class D(C):
    def f(self): pass

class E(D):
    pass

然后实现我们的get_defining_class函数:

def get_defining_class(target_cls, method_name):
    # 按MRO顺序遍历继承链
    for cls in target_cls.__mro__:
        # 检查当前类是否自己定义了该方法
        if method_name in cls.__dict__:
            return cls
    # 遍历完没找到的话返回None(也可以根据需求抛异常)
    return None

现在来验证效果,完全符合你的预期:

assert get_defining_class(E, 'f') == D
assert get_defining_class(D, 'f') == D
assert get_defining_class(C, 'f') == C
assert get_defining_class(E, 'g') is None  # 不存在的方法返回None

额外小技巧:如果拿到的是方法对象而不是方法名

如果你手里已经有一个方法对象(比如E().f),也可以用这个函数来查找,只需要先拿到实例的类和方法名:

e = E()
# 从实例方法对象中提取类和方法名
assert get_defining_class(e.__class__, e.f.__name__) == D

常见疑问解答

你之前问「遍历E.__mro__找'f'是否可行?」——这个方向完全对,只是要注意不能只检查hasattr,必须用__dict__来确认是当前类自己定义的方法,这样才能精准定位到第一个定义该方法的类,和Python实际调用方法时的查找逻辑完全一致。

备注:内容来源于stack exchange,提问作者user200783

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 10:59:30