주어진 모듈에서 주어진 클래스의 하위 클래스를 반복합니다.

StackOverflow https://stackoverflow.com/questions/44352

  •  09-06-2019
  •  | 
  •  

문제

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의 제안은 잘 작동하지만 좀 더 파이썬적으로 만들기 위해 제안하고 싶은 몇 가지 개선 사항이 있습니다.그들은 표준 라이브러리의 검사 모듈을 사용합니다.

  1. 다음을 사용하여 getattr 호출을 피할 수 있습니다. inspect.getmembers()
  2. 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'>)]
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top