2013-08-19 11 views
7

すべてのクラスをPythonモジュールから無名オブジェクトのリストに初期化する方法はありますか?モジュール内のすべてのクラスをリスト内の名前のないオブジェクトに初期化する

モジュールrulesには、クラスRuleのすべての子クラスが含まれています。そのため、私は彼らがすべてのメソッドrun()を実装します確信していると私は動的にそれらのクラスから開始されたオブジェクトのリストを持っていると思い__init__

の通話中に生成される属性nameを持つことになります。動的に初期化すると、明示的に名前を付ける必要はありません。

質問は以下のとおりです。

それは、モジュール内のすべてのクラスを反復処理することは可能ですか?

名前のないオブジェクトは開始できますか?

答えて

8

少なくとも2つの方法があります。クラスのサブクラスをすべて取得するには、クラスの__subclasses__()メソッドを呼び出します。あなたの親クラスがRule呼び出されたのであれば、あなたが呼び出すことができます。

rule_list = [cls() for cls in Rule.__subclasses__()] 

をこれはあなたにRuleのすべてのサブクラスを与える、および特定のモジュールで見つかったものにそれらを制限するものではありません。

モジュールへのハンドルがある場合は、そのコンテンツを反復処理できます。これと同じように:あなたはそれにその最初の引数としてクラスではないオブジェクトを与えれば

import rule 
rule_list = [] 
for name in dir(rule): 
    value = getattr(rule, name) 
    if isinstance(value, type) and issubclass(value, Rule): 
     rule_list.append(value()) 

は残念ながら、issubclassTypeErrorをスローします。だから何とかそれを処理しなければならない。

EDIT:issubclass @Blackknghtの提案に準拠しています。

+0

私の答えよりも優れています。 'inspect.isclass()'を使って 'TypeError'を避けることができます。 –

+0

@AntonisChristofides本当に、 'inspect.isclass()'をフィルタとして使うことができます。しかし、私は生産コードの 'inspect'モジュールから何も使用しないようにしています。 –

+0

'isinstance(value、type)'を使ってクラスがあることを確認することもできます。 (古いスタイルのクラスをサポートする必要がある場合は 'types.ClassType'もチェックする必要がありますが、代わりにそれらを避けるだけです) – Blckknght

関連する問題