在蟒蛇,给出一个模块X和a类Y,我怎么可以迭代,或者产生一个列表中的所有亚类的Y存在模块X?

有帮助吗?

解决方案

这里的一种方法来做到这一点:

import inspect

def get_subclasses(mod, cls):
    """Yield the classes in module ``mod`` that inherit from ``cls``"""
    for name, obj in inspect.getmembers(mod):
        if hasattr(obj, "__bases__") and cls in obj.__bases__:
            yield obj

其他提示

虽然Quamrana的建议,有几个可能的改进,我想建议,以使它更python.它们依赖于使用检查模块的标准图书馆。

  1. 你可以避免的getattr呼吁通过使用 inspect.getmembers()
  2. Try/赶上可以避免由使用 inspect.isclass()

与那些可以减少整个事情的一个列表理解,如果你喜欢:

def find_subclasses(module, clazz):
    return [
        cls
            for name, cls in inspect.getmembers(module)
                if inspect.isclass(cls) and issubclass(cls, clazz)
    ]

我可以建议既不是问题的答案,从克里斯*艾德礼和zacherates满足要求?我认为这一修改zacerates答案是:

def find_subclasses(module, clazz):
    for name in dir(module):
        o = getattr(module, name)
        try:
            if (o != clazz) and issubclass(o, clazz):
                yield name, o
        except TypeError: pass

原因我不同意给出的答案是,首先不产生课程,是一个遥远的子给类和第二类包括该给予类。

鉴于该模块的foo.py

class foo(object): pass
class bar(foo): pass
class baz(foo): pass

class grar(Exception): pass

def find_subclasses(module, clazz):
    for name in dir(module):
        o = getattr(module, name)

        try: 
             if issubclass(o, clazz):
             yield name, o
        except TypeError: pass

>>> import foo
>>> list(foo.find_subclasses(foo, foo.foo))
[('bar', <class 'foo.bar'>), ('baz', <class 'foo.baz'>), ('foo', <class 'foo.foo'>)]
>>> list(foo.find_subclasses(foo, object))
[('bar', <class 'foo.bar'>), ('baz', <class 'foo.baz'>), ('foo', <class 'foo.foo'>), ('grar', <class 'foo.grar'>)]
>>> list(foo.find_subclasses(foo, Exception))
[('grar', <class 'foo.grar'>)]
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top