私は、引数としてコマンドを受け取る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は、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()
これは問題なく機能します。このコードで行っていることを達成するためのもっと慣用的な方法があるのではないかと思っています。
私は特に卵や拡張ポイントの使用に乗り込みたくないことに注意してください。これはオープンソースプロジェクトではなく、「プラグイン」があるとは思いません。重要なのは、メインアプリケーションコードを簡素化し、新しいコマンドモジュールが追加されるたびにコードを変更する必要をなくすことです。