私は、コマンドを引数として受け取る Python アプリケーションを作成しています。たとえば、次のようになります。
$ python myapp.py command1
アプリケーションを拡張可能にしたい、つまり、メインのアプリケーション ソースを変更せずに、新しいコマンドを実装する新しいモジュールを追加できるようにしたいです。ツリーは次のようになります。
myapp/
__init__.py
commands/
__init__.py
command1.py
command2.py
foo.py
bar.py
したがって、アプリケーションが実行時に利用可能なコマンド モジュールを見つけて、適切なものを実行するようにする必要があります。
Python は__import__()
、モジュール名として文字列を受け取る関数を定義します。
__import__(name, globals=None, locals=None, fromlist=(), level=0)
関数はモジュール をインポートし
name
、指定されたglobals
と を使用してlocals
パッケージ コンテキストで名前をどのように解釈するかを決定します。 は、fromlist
によって指定されたモジュールからインポートする必要があるオブジェクトまたはサブモジュールの名前を提供しますname
。ソース:https://docs.python.org/3/library/functions.html#__import__
現時点では次のようなものがあります:
command = sys.argv[1]
try:
command_module = __import__("myapp.commands.%s" % command, fromlist=["myapp.commands"])
except ImportError:
# Display error message
command_module.run()
これは問題なく動作しますが、このコードで実行している操作をより慣用的な方法で実行できるかどうかが疑問です。
特に、egg や拡張ポイントの使用には触れたくないことに注意してください。これはオープンソース プロジェクトではないため、「プラグイン」が存在するとは考えていません。重要なのは、メインのアプリケーション コードを簡素化し、新しいコマンド モジュールが追加されるたびにコードを変更する必要がないようにすることです。
ベストアンサー1
Python 2.7/3.1 より古いバージョンでは、ほぼ同じ方法で実行できます。
新しいバージョンについてはimportlib.import_module
、Python 2そしてPython3 について。
または、__import__
次のようにしてモジュールのリストをインポートすることもできます。
>>> moduleNames = ['sys', 'os', 're', 'unittest']
>>> moduleNames
['sys', 'os', 're', 'unittest']
>>> modules = map(__import__, moduleNames)
そのまま切り取ったPythonに飛び込もう。