web-dev-qa-db-ja.com

モジュールで定義されているがインポートされていないすべてのクラスを取得するにはどうすればよいですか?

私はすでに次の質問を見ましたが、それは私が望む場所を完全に取得しません: Pythonの現在のモジュール内のすべてのクラスのリストを取得するにはどうすればよいですか?

特に、インポートされるクラスは必要ありません。次のモジュールがある場合:

_from my.namespace import MyBaseClass
from somewhere.else import SomeOtherClass

class NewClass(MyBaseClass):
    pass

class AnotherClass(MyBaseClass):
    pass

class YetAnotherClass(MyBaseClass):
    pass
_

リンクされた質問で受け入れられている回答が示唆するようにclsmembers = inspect.getmembers(sys.modules[__name__], inspect.isclass)を使用すると、このモジュールで定義されている3つに加えてMyBaseClassSomeOtherClassが返されます。

NewClassAnotherClassYetAnotherClassのみを取得するにはどうすればよいですか?

44
Davy8

__module__クラスの属性。定義されたモジュールを確認します。

このような古い質問に答えたことをお詫び申し上げますが、このソリューションにinspectモジュールを使用することに抵抗を感じていました。本番環境での使用が安全ではない場所を読んだことがあります。

モジュール内のすべてのクラスをリスト内の名前のないオブジェクトに初期化します

Antonis Christofidesの回答1へのコメント を参照してください。

変数がクラスかどうかを確認する方法 からオブジェクトがクラスであるかどうかをテストするための答えを得ました

これが私の検査不要のソリューションです

def classesinmodule(module):
    md = module.__dict__
    return [
        md[c] for c in md if (
            isinstance(md[c], type) and md[c].__module__ == module.__name__
        )
    ]

classesinmodule(modulename)
12
piRSquared

標準ライブラリの「Pythonクラスブラウザ」モジュールの使用を検討することもできます: http://docs.python.org/library/pyclbr.html

問題のモジュールを実際に実行するわけではないので(代わりに単純なソース検査を行います)、正しく理解できない特定の手法がいくつかありますが、すべての「通常の」クラス定義について、それらは正確に記述されます。

8
ncoghlan

私は以下を使用しました:

# Predicate to make sure the classes only come from the module in question
def pred(c):
    return inspect.isclass(c) and c.__module__ == pred.__module__
# fetch all members of module __name__ matching 'pred'
classes = inspect.getmembers(sys.modules[__name__], pred)

現在のモジュール名を入力したくありませんでした

7
rmc
from pyclbr import readmodule

clsmembers = readmodule(__name__).items()
2
drruggeri