3

ディレクトリに多数の Python モジュールがあり、すべてが派生クラスです。モジュールごとに、その中にあるクラスをインスタンス化し(実際のクラス名はモジュールファイル名で構築できます)、それぞれで「go」メソッドを呼び出す「ランナー」スクリプトが必要です。

モジュールがいくつあるかはわかりませんが、「bot_*.py」のようなものを介してディレクトリをグロブするすべてのモジュールを一覧表示できます

これは「メタプログラミング」に関するものだと思いますが、それを行うための最良の (最もエレガントな) 方法は何でしょうか?

4

4 に答える 4

4

を使用__import__()して各モジュールをロードdir()し、各モジュール内のすべてのオブジェクトを検索し、クラスであるすべてのオブジェクトを検索してインスタンス化し、go()メソッドを実行することができます。

import types
for module_name in list_of_modules_to_load:
    module = __import__(module_name)
    for name in dir(module):
        object = module.__dict__[name]
        if type(object) == types.ClassType:
            object().go()
于 2009-01-23T18:43:50.473 に答える
3
def run_all(path):
    import glob, os
    print "Exploring %s" % path
    for filename in glob.glob(path + "/*.py"):
        # modulename = "bot_paperino"
        modulename = os.path.splitext(os.path.split(filename)[-1])[0]
        # classname = "Paperino"
        classname = modulename.split("bot_")[-1].capitalize()
        # package = "path.bot_paperino"
        package = filename.replace("\\", "/").replace("/", ".")[:-3]
        mod = __import__(package)
        if classname in mod.__dict__[modulename].__dict__.keys():
            obj = mod.__dict__[modulename].__dict__[classname]()
            if hasattr(obj, "go"):
                obj.go()

if __name__ == "__main__":
    import sys
    # Run on each directory passed on command line
    for path in sys.argv[1:]:
        run_all(sys.argv[1])

__init__.py「実行」する各パスに が必要です。「bot_」は自由に変更してください。Windows と Linux で実行します。

于 2009-01-23T20:00:25.327 に答える
1

私は試してみます:

import glob
import os

filelist = glob.glob('bot_*.py')
for f in filelist:
    context = {}
    exec(open(f).read(), context)
    klassname = os.path.basename(f)[:-3] 
    klass = context[klassname]
    klass().go()

これは、モジュールに似た名前のクラスのみを実行します。これはあなたが望むものだと思います。また、最上位ディレクトリをパッケージにする必要もありません。

glob は前のディレクトリを含む完全なパスを返すことに注意してください。したがって、クラス名を取得するには os.path.basename(f)[:-3] を使用してください。

于 2009-01-23T19:35:36.607 に答える
1

これは、モジュールの構造を少し推測する必要がある私の頭の上からこれを行う1つの方法です。

メインディレクトリ/
  ランナー.py
  パッケージ/
    __init__.py
    bot_moduleA.py
    bot_moduleB.py
    bot_moduleC.py

ランナーでは、これを見つけることができます:


import types
import package

for moduleName in dir(package):
  module = package.__dict__[moduleName]
  if type(module) != types.ModuleType:
    continue

  for klassName in dir(module):
    klass = module.__dict__[klassName]
    if type(klass) != types.ClassType:
      continue
    klass().go()
于 2009-01-23T18:49:37.450 に答える