-mスイッチの目的は何ですか?


174

通話の違いは何ですか?

python -m mymod1 mymod2.py args

そして

python mymod1.py mymod2.py args

どちらの場合mymod1.pyも呼び出されているようsys.argvです

['mymod1.py', 'mymod2.py', 'args']

それで、-mスイッチは何ですか?


私が間違っているが、デフォルトのライブラリパスで-m検索しmymod1ているように見える場合は修正してください。例:python -m SimpleHTTPServer動作しpython SimpleHTTPServerますが、で失敗しcan't open file 'SimpleHTTPServer': [Errno 2] No such file or directoryます。
Basj

7
私は実際にここに答えは明確た:stackoverflow.com/questions/46319694/...
Casebash

回答:


137

PEP 338Rationaleセクションの最初の行は次のように述べています。

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の残りの部分が何であるかだことなど、パッケージの一部であるモジュールでの作業のように、可能です。詳細については、こちらをお読みください。


47
の私のお気に入りの使い方は-mですpython -m SimpleHTTPServer。USBフラッシュドライブを使用せずにいくつかのファイルを共有する必要があるときに本当に便利です。
Arifwn

21
@arifwn Python3の実行にはわずかな更新が必要であり、python -m http.serverこれはまだ素晴らしいです!
キットRoed

12
TL; DR:1)実行できpython -m package.subpackage.module、通常の解決機構が使用され.pyます。正確なファイルを指定する必要はありません。2)パッケージは途中でロードされるため、回避策なしで、実行中のモジュールから相対インポートを実行できます。3)絶対インポートは、.pyファイルが存在するディレクトリではなく、現在のディレクトリに基づいて行われます(スクリプトがにある場合''sys.path、ではなく、の先頭に/path/to/myあります/path/to/my/script.py)。
16

この答えが明確にしていないことは、これは実行可能な、つまり__main__.pyファイルを持つモジュールのサブセットでのみ機能することです。ほとんどのpython -m sys 'print(sys.version)'場合、失敗しませんpython: No code object available for sys。たとえば、で失敗します。答えでそれを明確にすることを提案します。
smci

19

これは、パッケージにファイルがある場合にのみ機能する__main__.pyことに言及する価値があります。それ以外の場合、このパッケージは直接実行できません。

python -m some_package some_arguments

pythonインタープリターは__main__.py、実行するパッケージパスでファイルを探します。これは次と同等です。

python path_to_package/__main__.py somearguments

次の後にコンテンツを実行します。

if __name__ == "__main__":

2
パッケージのinitファイルはどうですか?メインファイルがある場合、initも呼び出されますか?
変数

@variableはいinit .pyはメイン .pyが呼び出される前に呼び出されます
Mark Rucker

1

この質問が何度も尋ねられて回答されたにもかかわらず(たとえば、ここここここここここ)、私の意見では、既存の回答では-m旗のすべての意味を完全にまたは簡潔に捉えていません。したがって、以下は以前に来たことを改善しようとします。

はじめに(TLDR)

-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つの注目すべき使用例があります。

  1. ファイル名がわからない可能性のあるコマンドラインからモジュールを実行する。この使用例は、Pythonインタープリターがモジュール名をファイル名に変換する方法を知っているという事実を利用しています。これは、コマンドラインからstdlibモジュールまたはサードパーティモジュールを実行する場合に特に有利です。たとえば、http.serverモジュールのファイル名を知っている人はほとんどいませんが、ほとんどの人はそのモジュール名を知っているので、を使用してコマンドラインから実行できpython -m http.serverます。

  2. インストールする必要なしに、絶対インポートを含むローカルパッケージを実行するには この使用例は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 packagenamestackoverflow.com/a/53772635/1779091
変数
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.