2009-05-26 16 views
12

"子"モジュールを別のモジュールにインポートしてその属性をリストするのはかなり簡単ですが、すべての子モジュールをインポートするのが少し難しくなります。Pythonですべての子モジュールを見つけるには?

私は、既存の3Dアプリケーション用のツールライブラリを構築しています。各ツールには、それぞれ独自のメニュー項目とサブメニューがあります。コンテキストやテンプレートに基づいて多くのメニューが変更されるため、ツールに独自のメニューを作成する責任があります。私はベースモジュールがすべての子モジュールを見つけてcreate_menu()関数をチェックし、見つかったらそれを呼び出すことができるようにしたいと思います。

すべての子モジュールを検出する最も簡単な方法は何ですか?私は私が私のモジュラーIRCボットのためにこれを書いている種類やPythonで始まったばかりでプログラミングしたときdir()imp module

+0

これは関連していますか? [(setuptoolsパッケージの 'pkg_resources')](http://jeetworks.org/node/49) –

+1

[pkgutil.walk_packages](http://docs.python.org/library/pkgutil.html#pkgutil。 walk_packages)。 – Dag

+1

モジュールは@Dagのようにパッケージ –

答えて

0


    # Load plugins 

    _plugins = [] 

    def ifName(name): 
     try: 
      return re.match('([^_.].+)\.[^.]+', a).group(1) 
     except: 
      return None 

    def isValidPlugin(obj): 
     from common.base import PluginBase 
     try: 
      if obj.__base__ == PluginBase: 
       return True 
      else: 
       return False 
     except: 
      return False 

    plugin_names = set(ifilter(lambda a: a!=None, [ifName(a) for a in os.listdir(os.path.join(os.getcwd(), 'plugins'))])) 
    for plugin_name in plugin_names: 
     try: 
      plugin = __import__('plugins.'+plugin_name, fromlist=['plugins']) 
      valid_plugins = filter(lambda a: isValidPlugin(a), [plugin.__getattribute__(a) for a in dir(plugin)]) 
      _plugins.extend(valid_plugins) 
     except Exception, e: 
      logger.exception('Error loading plugin %s', plugin_name) 

    # Run plugins 

    _plugins = [klass() for klass in _plugins] 

それが安全か「正しい」方法ではありません、それにもかかわらず我々は役に立つだろう。それは非常に古いコードなので私を打ち負かさないでください。

+0

私は必要とする正確なモジュールのように見えます!ありがとう。 – Soviut

+11

それはかなり簡潔な答えです、私はそれが受け入れられた理由はわかりません。 dir()のドキュメントはあなたのオブジェクトがすでに属性を持っていることを前提としています。あなたは、まだインポートされていないモジュールを見つけるためにdir()を使うべきですか? – bignose

+3

いいえ: '$は、mkdir fooという $タッチFOO/__ init__.py $タッチFOO/bar.py $パイソン のPython 2.7.1+(R271:86832、2011年4月11日、18時05分24秒) [GCC 4.5.2] on linux2 詳細については、 "help"、 "copyright"、 "credits"または "license"と入力してください。 >>>インポートFOO >>> FOO <からモジュール 'FOO' 'FOO/__ INIT __。PY'> >>> DIR(FOO) [ '__builtins__'、 '__doc__'、 '__FILE__'、「__name__ '、' __package__ '、' __path__ '] >>> fooインポートバーから >>> bar から 'module' foo.bar '>' –

1

を使用して

+0

はい、dfaのようなimpモジュールを使用してください。 – deno

-1

あなたはディレクトリをBING globを試すことができます:私は、プラグインのこの種のものを行うための最善の方法は、entry_pointsを使用していると思わ

checked_modules 
for module in modules: 
    try: 
     __import__(module, globals(), locals()) # returns module object 
    except ImportError: 
     pass 
    else: 
     checked_modules.append(module) 
3

と:そして、あなたがそれらをインポートしようとすることができ

import os 
import glob 

modules = glob.glob(os.path.join('/some/path/to/modules', '*.py')) 

API for querying them

+0

これは受け入れられる回答でなければなりません。エントリーポイント経由でモジュールを登録することは、実行時にそれらを発見したいときにははるかに明確で、意図的なPythonのアプローチであり、 'pkgutil.walk_packages'が行うような方法ですべてのモジュールをインポートするという副作用はありません。 –

1

すべてのプラグインをファイルシステムベースのモジュールとして実装している限り、サブモジュールを見つけるためのファイルシステムを横切る上記のソリューションは問題ありません。

もっと柔軟な方法は、メインモジュールの明示的なプラグインリストであり、すべてのプラグイン(ファイル、ダイナミック、またはクラスのインスタンスによって作成されたモジュール)がそのリストに明示的に追加されるかどうかに関係なくあります。たぶんregisterPlugin関数を介して。

覚えておいてください: "明示的ではありませんより暗黙的です"は、Pythonの禅の一部です。

+0

これを動作させるには、アプリケーションの起動時にプラグインモジュールをインポートする方法が必要です。そうしないと、自分自身を登録する機会がありません。それは鶏と卵の問題です。モジュールをトラバース/自動インポートせずにメインモジュールのすべてのモジュールを手動でインポートすると、登録機能の必要はなくなりますが、メインが特定のプラグインについて知る必要がないという原則を破ってしまいます – Anentropic

関連する問題