遍历给定模块中某类的子类

19 投票
4 回答
12725 浏览
提问于 2025-04-11 09:20

在Python中,假设你有一个模块X和一个类Y,怎么才能遍历或者生成一个包含模块X中所有Y类的子类的列表呢?

4 个回答

5

我想说,Chris AtLee 和 zacherates 的答案都没有满足要求。 我觉得对 zacherates 答案的这个修改更好:

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

我不同意这些答案的原因是,第一个答案生成的类并不是给定类的远亲子类,而第二个答案则包含了给定类。

25

虽然Quamrana的建议很好,但我想提出几个可能的改进,让它更符合Python的风格。这些改进依赖于使用标准库中的inspect模块。

  1. 你可以通过使用 inspect.getmembers() 来避免调用getattr。
  2. 你可以通过使用 inspect.isclass() 来避免使用try/catch。

有了这些,你可以把整个过程简化成一个列表推导式,如果你愿意的话:

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

这里有一种方法可以实现:

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

撰写回答