通話の違いは何ですか?
python -m mymod1 mymod2.py args
そして
python mymod1.py mymod2.py args
どちらの場合mymod1.py
も呼び出されているようsys.argv
です
['mymod1.py', 'mymod2.py', 'args']
それで、-m
スイッチは何ですか?
通話の違いは何ですか?
python -m mymod1 mymod2.py args
そして
python mymod1.py mymod2.py args
どちらの場合mymod1.py
も呼び出されているようsys.argv
です
['mymod1.py', 'mymod2.py', 'args']
それで、-m
スイッチは何ですか?
回答:
PEP 338のRationale
セクションの最初の行は次のように述べています。
Python 2.4は、コマンドラインスイッチ-mを追加して、スクリプトとして実行するためにPythonモジュールの名前空間を使用してモジュールを配置できるようにします。動機付けとなる例は、pdbやprofileなどの標準ライブラリモジュールでしたが、Python 2.4実装はこの限られた目的には適しています。
したがって、現在のディレクトリ内のファイルだけでなく、この方法でPythonの検索パスに任意のモジュールを指定できます。あなたは正しいですpython mymod1.py mymod2.py args
が、まったく同じ効果があります。Scope of this proposal
セクションの最初の行は次のように述べています:
Python 2.4では、-mを使用して配置されたモジュールは、コマンドラインでファイル名が指定されたかのように実行されます。
-m
より多くのPEP 338の残りの部分が何であるかだことなど、パッケージの一部であるモジュールでの作業のように、可能です。詳細については、こちらをお読みください。
-m
ですpython -m SimpleHTTPServer
。USBフラッシュドライブを使用せずにいくつかのファイルを共有する必要があるときに本当に便利です。
python -m http.server
これはまだ素晴らしいです!
python -m package.subpackage.module
、通常の解決機構が使用され.py
ます。正確なファイルを指定する必要はありません。2)パッケージは途中でロードされるため、回避策なしで、実行中のモジュールから相対インポートを実行できます。3)絶対インポートは、.py
ファイルが存在するディレクトリではなく、現在のディレクトリに基づいて行われます(スクリプトがにある場合''
はsys.path
、ではなく、の先頭に/path/to/my
あります/path/to/my/script.py
)。
__main__.py
ファイルを持つモジュールのサブセットでのみ機能することです。ほとんどのpython -m sys 'print(sys.version)'
場合、失敗しませんpython: No code object available for sys
。たとえば、で失敗します。答えでそれを明確にすることを提案します。
これは、パッケージにファイルがある場合にのみ機能する__main__.py
ことに言及する価値があります。それ以外の場合、このパッケージは直接実行できません。
python -m some_package some_arguments
pythonインタープリターは__main__.py
、実行するパッケージパスでファイルを探します。これは次と同等です。
python path_to_package/__main__.py somearguments
次の後にコンテンツを実行します。
if __name__ == "__main__":
この質問が何度も尋ねられて回答されたにもかかわらず(たとえば、ここ、ここ、ここ、ここ、ここ)、私の意見では、既存の回答では-m
旗のすべての意味を完全にまたは簡潔に捉えていません。したがって、以下は以前に来たことを改善しようとします。
-m
コマンドがすべてではないそれらのものの多くは、必ずしもすべての時間を必要とするだろうし。要するにそれは:(1)は、Pythonスクリプトは、モジュール名ではなく、ファイル名を介して実行することが可能になります(2)1をに追加するディレクトリを選択することを可能にするsys.path
ためにimport
解決の(3)コマンドラインから相対インポートを含むPythonスクリプトを実行できるようにします。
-m
フラグを説明するには、最初に少し用語を明確にする必要があります。
まず、Pythonの主要な組織単位は、 モジュールます。モジュールには、コードモジュールとパッケージモジュールの2つの種類があります。コードモジュールは、Python実行可能コードを含む任意のファイルです。パッケージモジュールは、他のモジュール(コードモジュールまたはパッケージモジュール)を含むディレクトリです。コードモジュールの最も一般的なタイプは*.py
ファイルですが、パッケージモジュールの最も一般的なタイプは、__init__.py
ファイルです。
第二に、すべてのモジュールを一意に2つの異なる方法で同定することができる:<modulename>
および<filename>
。モジュールは、Pythonコードのモジュールimport <modulename>
名(例:)とコマンドラインのファイル名(例:python <filename>
。すべてのPythonインタープリターは、明確に定義された一連のルールを使用して、モジュール名をファイル名に変換できます。これらのルールはsys.path
変数に依存するため、この値を変更することでマッピングを変更できます(これがどのように行われるかの詳細については、PEP 302を参照してください)。
3番目に、すべてのモジュール(コードとパッケージの両方)を実行できます(これにより、モジュールに関連付けられたコードがPythonインタープリターによって評価されます)。実行方法とモジュールのタイプに応じて、どのコードがいつ評価されるかは、かなり変化する可能性があります。たとえば、パッケージモジュールを実行すると、評価されpython <filename>
、その後<filename>/__init__.py
にが続き<filename>/__main__.py
ます。一方、同じパッケージモジュールを経由して実行するとimport <modulename>
、パッケージのみ__init__.py
が実行されます。
-m
-mフラグはPython 2.4.1で初めて導入されました。当初、その唯一の目的は、実行するPythonモジュールを識別する代替手段を提供することでした。我々は両方知っていた場合であること、<filename>
および<modulename>
モジュールのため、次の2つのコマンドは同等であった:python <filename> <args>
とpython -m <modulename> <args>
。さらに、PEP 338によるとこの反復は-m
最上位のモジュール名(つまり、パッケージを介在させずにsys.pathに直接見つけることができるモジュール)でのみ機能しました。
終了とPEP 338-m
の機能はサポートするように拡張された<modulename>
トップレベルのないモジュールを超え表現を。これにより、などの名前http.server
が完全にサポートされるようになりました。この機能強化により、モジュール内のすべてのパッケージ__init__.py
がモジュール自体とともにロードされるようになりました(つまり、すべてのパッケージファイルが評価されました)。
の最後の主要な機能拡張-m
は、PEP 366に付属しています。この更新-m
により、絶対インポートだけでなく、明示的な相対インポートもサポートする機能が追加されました。これは__package__
、-m
コマンドで指定されたモジュールの変数を変更することによって実現されました。
-mフラグには2つの注目すべき使用例があります。
ファイル名がわからない可能性のあるコマンドラインからモジュールを実行する。この使用例は、Pythonインタープリターがモジュール名をファイル名に変換する方法を知っているという事実を利用しています。これは、コマンドラインからstdlibモジュールまたはサードパーティモジュールを実行する場合に特に有利です。たとえば、http.server
モジュールのファイル名を知っている人はほとんどいませんが、ほとんどの人はそのモジュール名を知っているので、を使用してコマンドラインから実行できpython -m http.server
ます。
インストールする必要なしに、絶対インポートを含むローカルパッケージを実行するには この使用例はPEP 338で詳しく説明されてsys.path
おり、モジュールのディレクトリではなく、現在の作業ディレクトリが追加されるという事実を利用しています。この使用例はpip install -e .
、開発/編集モードでのパッケージのインストールに使用する場合と非常に似ています。
-m
長年にわたって行われたすべての拡張機能には、1つの大きな欠点があります。Pythonで記述されたコードモジュール(* .py)しか実行できないことです。たとえば-m
、Cコンパイル済みコードモジュールの実行に使用した場合、次のエラーが生成されますNo code object available for <modulename>
(詳細については、こちらを参照してください)。
Pythonコマンドによるモジュール実行の影響(つまり、python <filename>
):
sys.path
最終ディレクトリを含むように変更されます <filename>
__name__
に設定されています '__main__'
__package__
に設定されています None
__init__.py
どのパッケージに対しても評価されません(パッケージモジュールの独自のものを含む)__main__.py
パッケージモジュールについて評価されます。コードはコードモジュールに対して評価されます。importステートメント(つまりimport <modulename>
)によるモジュール実行の影響:
sys.path
ではない任意の方法で変更__name__
の絶対形式に設定されます <modulename>
__package__
の直接の親パッケージに設定されます <modulename>
__init__.py
すべてのパッケージに対して評価されます(パッケージモジュールの独自のパッケージを含む)__main__.py
されていないパッケージのモジュールのために評価。コードはコードモジュールに対して評価されます-mフラグによるモジュール実行の影響(つまり、python -m <modulename>
):
sys.path
現在のディレクトリを含むように変更されます__name__
に設定されています '__main__'
__package__
の直接の親パッケージに設定されます <modulename>
__init__.py
すべてのパッケージに対して評価されます(パッケージモジュールの独自のパッケージを含む)__main__.py
パッケージモジュールについて評価されます。コードはコードモジュールに対して評価されます-m
フラグは、その最も単純でないモジュールではなくファイル名を使用してコマンドラインからPythonスクリプトを実行するための手段です。さらに、ステートメントの-m
機能import
(明示的な相対インポートや自動パッケージ__init__
評価のサポートなど)とpythonコマンドラインの利便性を組み合わせた追加機能を提供します。
python -m packagename
:stackoverflow.com/a/53772635/1779091
-m
検索しmymod1
ているように見える場合は修正してください。例:python -m SimpleHTTPServer
動作しpython SimpleHTTPServer
ますが、で失敗しcan't open file 'SimpleHTTPServer': [Errno 2] No such file or directory
ます。