문제
Python에서 모듈 X와 클래스 Y가 주어지면 모듈 X에 존재하는 Y의 모든 하위 클래스 목록을 어떻게 반복하거나 생성할 수 있습니까?
해결책
이를 수행하는 한 가지 방법은 다음과 같습니다.
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의 제안은 잘 작동하지만 좀 더 파이썬적으로 만들기 위해 제안하고 싶은 몇 가지 개선 사항이 있습니다.그들은 표준 라이브러리의 검사 모듈을 사용합니다.
- 다음을 사용하여 getattr 호출을 피할 수 있습니다.
inspect.getmembers()
- try/catch는 다음을 사용하여 피할 수 있습니다.
inspect.isclass()
원하는 경우 이를 사용하여 모든 것을 단일 목록 이해로 줄일 수 있습니다.
def find_subclasses(module, clazz):
return [
cls
for name, cls in inspect.getmembers(module)
if inspect.isclass(cls) and issubclass(cls, clazz)
]
Chris AtLee와 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'>)]
제휴하지 않습니다 StackOverflow