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

kdt*_*kdt 33 python inheritance

有没有办法在python中查询从特定类继承的类的命名空间?给定一个类,widget我希望能够调用类似于inheritors(widget)获取所有不同类型的小部件的列表.

Dun*_*can 53

您想用来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
Run Code Online (Sandbox Code Playgroud)

注意如果您使用的是Python 2.x,则仅适用于新式类.

  • @KashifSiddiqui是不正确的。__subclasses__包括所有子类,无论它们在何处声明。但是,直到定义了相关的子类之后,它们才会显示出来,因此,如果仅在定义基类的模块末尾提取子类列表,则其他模块中的子类将不存在。 (2认同)
  • @KashifSiddiqui,是的,因为在导入它们之前它们不是子类,它们只是文件中的一些文本。因此,您导入了一堆文件,然后需要知道它们定义的所有子类。这是一个很常见的场景。 (2认同)

Imr*_*ran 17

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

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'>]})
Run Code Online (Sandbox Code Playgroud)

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

  • Python的`__subclass __()`方法已经为你跟踪了子类关系. (3认同)
  • 感谢您指出,完全忘记了这一点。我的解决方案还跟踪间接子类,即您在答案中谈到的额外工作。 (2认同)