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

如何在Python中可靠获取当前类方法的模块与类信息(支持继承、动态创建)

解决类方法继承/元类场景下定义模块与类的识别问题

Python中类方法通过cls参数绑定调用它的类,这导致在继承或元类创建的类中,直接通过cls.__module__和cls.__name__只能拿到调用时的类信息,而非方法实际定义的类和模块。要解决这个问题,可以通过自定义装饰器在方法定义阶段就捕获并存储原始定义信息。

核心方案:定义跟踪装饰器

编写一个装饰器,在方法定义时记录它的原始模块和所属类,后续调用时直接读取这些预存的信息即可,不受继承层级或元类影响:

def track_definition(func):
    # 记录方法定义所在的模块
    func._defined_module = func.__module__
    
    # 处理类方法:类方法的原始函数存储在__func__属性中
    if isinstance(func, classmethod):
        original_func = func.__func__
        # 通过__qualname__拆分出所属类名(格式为"ClassName.MethodName")
        qualname_parts = original_func.__qualname__.split('.')
        func._defined_class = qualname_parts[-2]
    # 可扩展支持静态方法、实例方法等
    elif isinstance(func, staticmethod):
        original_func = func.__func__
        qualname_parts = original_func.__qualname__.split('.')
        func._defined_class = qualname_parts[-2] if len(qualname_parts) >=2 else None
    else:
        qualname_parts = func.__qualname__.split('.')
        func._defined_class = qualname_parts[-2] if len(qualname_parts) >=2 else None
    
    return func

基础继承场景测试

将装饰器应用到类方法上,即可在调用时区分调用类和定义类:

class BaseClass:
    @track_definition
    @classmethod
    def mymethod(cls):
        print(f"调用类: {cls.__module__}.{cls.__name__}")
        print(f"定义类: {mymethod._defined_module}.{mymethod._defined_class}")

class DerivedClass(BaseClass):
    pass

DerivedClass.mymethod()

输出结果:

调用类: __main__.DerivedClass
定义类: __main__.BaseClass

元类场景适配

如果类是通过元类创建的,只需在元类的__new__方法中自动为方法添加装饰器,即可同样生效:

class Meta(type):
    def __new__(cls, name, bases, attrs):
        # 遍历类属性,为可调用对象添加定义跟踪装饰器
        for attr_name, attr_value in attrs.items():
            if callable(attr_value) or isinstance(attr_value, (classmethod, staticmethod)):
                attrs[attr_name] = track_definition(attr_value)
        return super().__new__(cls, name, bases, attrs)

class BaseMetaClass(metaclass=Meta):
    @classmethod
    def meta_method(cls):
        print(f"调用类: {cls.__module__}.{cls.__name__}")
        print(f"定义类: {meta_method._defined_module}.{meta_method._defined_class}")

class DerivedMeta(BaseMetaClass):
    pass

DerivedMeta.meta_method()

输出结果:

调用类: __main__.DerivedMeta
定义类: __main__.BaseMetaClass

原理说明

  • __module__属性:在方法定义时就固定指向定义该方法的模块,不会随继承改变。
  • __qualname__属性:记录方法的完整限定名称(包含所属类),通过拆分该字符串可以准确获取方法定义时的所属类。
  • 装饰器在方法定义阶段执行,将这些信息存储为自定义属性(如_defined_module、_defined_class),后续调用时直接读取即可,完全不受调用时的类绑定影响。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 20:15:10