17

Pythonでは、モジュールXとクラスYが与えられた場合、モジュールXに存在するYのすべてのサブクラスのリストを反復または生成するにはどうすればよいですか?

4

4 に答える 4

21

Quamranaの提案は問題なく機能しますが、よりPythonicにするために、いくつかの改善点を提案したいと思います。それらは、標準ライブラリのinspectモジュールの使用に依存しています。

  1. を使用してgetattr呼び出しを回避できますinspect.getmembers()
  2. トライ/キャッチは、を使用することで回避できますinspect.isclass()

これらを使用すると、必要に応じて、すべてを1つのリスト内包に減らすことができます。

def find_subclasses(module, clazz):
    return [
        cls
            for name, cls in inspect.getmembers(module)
                if inspect.isclass(cls) and issubclass(cls, clazz)
    ]
于 2009-01-03T01:56:21.720 に答える
12

これを行う1つの方法は次のとおりです。

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
于 2008-09-04T18:20:21.087 に答える
4

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

私が与えられた答えに同意しない理由は、最初の答えは与えられたクラスの遠いサブクラスであるクラスを生成せず、2番目の答えには与えられたクラスが含まれているからです。

于 2008-09-05T22:54:42.557 に答える
1

モジュール 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'>)]
于 2008-09-04T18:29:59.847 に答える