4

呼び出したときに、elixir \ sqlalchemyがモデルで宣言したすべてのエンティティクラスをどのように知るのか、迷っていましたsetup_all()。私の小さなプロジェクトではそのような機能が必要ですが、手がかりがありません。elixirをステップトレースしようとしましsetup_all()たが、すべてのエンティティクラスのコレクションが「グローバル」リストに保持されていることがわかりました(またはdictでしたか?)が、リストがいっぱいになった瞬間を捉えることができません。何か案は?

4

2 に答える 2

10

クラス定義の場合、これは簡単です(インポートなし)

def find_subclasses(cls):
    results = []
    for sc in cls.__subclasses__():
        results.append(sc)
    return results

これが欲しいのか、それともオブジェクトが欲しいのかわかりません。オブジェクトが必要な場合:

import gc

def find_subclasses(cls):
    results = []
    for sc in cls.__subclasses__():
        for obj in gc.get_objects():
            if isinstance(obj, sc):
               results.append(obj)
    return results
于 2012-01-22T16:13:27.843 に答える
4

SQLALchemyやelixirとまったく連携せずに、主な質問に答えます-はい、Pythonで可能です。

標準ライブラリのガベージコレクタ(gc)モジュールには、インタプリタ全体で特定のオブジェクトへのすべての参照を取得できるようにする関数呼び出しがあります。__mro__ クラスは、継承されたクラスの属性で常に参照されます。

したがって、次の関数は、特定のクラスから継承するすべてのクラスを取得できます。

import gc
def find_subclasses(cls):
    all_refs = gc.get_referrers(cls)
    results = []
    for obj in all_refs:
        # __mro__ attributes are tuples
        # and if a tuple is found here, the given class is one of its members
        if (isinstance(obj, tuple) and
            # check if the found tuple is the __mro__ attribute of a class
            getattr(obj[0], "__mro__", None) is obj):
            results.append(obj[0])
    return results
于 2012-01-21T22:04:06.833 に答える