たとえば、コマンドとして引数を取る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)
関数はモジュール名をインポートし、パッケージコンテキストで名前を解釈する方法を決定するために、指定されたグローバルとローカルを使用する可能性があります。fromlistは、名前で指定されたモジュールからインポートする必要があるオブジェクトまたはサブモジュールの名前を示します。
ソース: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()
これは問題なく機能します。このコードで実行していることを達成するためのより慣用的な方法があるのではないかと思っています。
特に卵や拡張ポイントを使いたくありません。これはオープンソースプロジェクトではないため、「プラグイン」が存在するとは思わない。重要なのは、メインアプリケーションコードを簡略化し、新しいコマンドモジュールが追加されるたびにコードを変更する必要をなくすことです。
dir(__import__)
。fromlistは、「from name import ...」をエミュレートする名前のリストである必要があります。