遍历给定模块中某类的子类
在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模块。
- 你可以通过使用
inspect.getmembers()
来避免调用getattr。 - 你可以通过使用
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