Python:找到从这个继承的所有类?

时间:2011-05-04 10:20:10

标签: python inheritance

在python中是否有任何方法可以查询从特定类继承的类的命名空间?鉴于课程widget,我希望能够调用类似inheritors(widget)的内容来获取所有不同类型的小部件列表。

4 个答案:

答案 0 :(得分:52)

您希望使用Widget.__subclasses__()来获取所有子类的列表。它只查找直接子类,但如果你想要所有这些,你将不得不做更多的工作:

def inheritors(klass):
    subclasses = set()
    work = [klass]
    while work:
        parent = work.pop()
        for child in parent.__subclasses__():
            if child not in subclasses:
                subclasses.add(child)
                work.append(child)
    return subclasses

N.B。如果您使用的是Python 2.x,则仅适用于新式类。

答案 1 :(得分:16)

您可以使用自己的元类跟踪继承

import collections

class A(object):
    class __metaclass__(type):
        __inheritors__ = defaultdict(list)

        def __new__(meta, name, bases, dct):
            klass = type.__new__(meta, name, bases, dct)
            for base in klass.mro()[1:-1]:
                meta.__inheritors__[base].append(klass)
            return klass

class B(A):
    pass

class C(B):
    pass

>>> A.__inheritors__
defaultdict(<type 'list'>, {<class '__main__.A'>: [<class '__main__.B'>, <class '__main__.C'>], <class '__main__.B'>: [<class '__main__.C'>]})

将跟踪从A或其派生类继承的任何内容。当加载应用程序中的所有模块时,您将获得完整的继承映射。

答案 2 :(得分:2)

# return list of tuples (objclass, name) containing all subclasses in callers' module
def FindAllSubclasses(classType):
    import sys, inspect
    subclasses = []
    callers_module = sys._getframe(1).f_globals['__name__']
    classes = inspect.getmembers(sys.modules[callers_module], inspect.isclass)
    for name, obj in classes:
        if (obj is not classType) and (classType in inspect.getmro(obj)):
            subclasses.append((obj, name))
    return subclasses

答案 3 :(得分:1)

你必须遍历全局命名空间中的所有对象(globals())并检查相关的对象/类是否是其他类的子类(检查用于issubclass()的Python文档)。