-mオプションを使用した、または使用しないPythonコードの実行
-m
フラグを使用します。
スクリプトがある場合も結果はほとんど同じですが、-m
フラグを使用せずにパッケージを開発する場合、パッケージ内のサブパッケージまたはモジュールをメインエントリとして実行する場合、インポートを正しく機能させる方法はありません。あなたのプログラムを指します(そして私を信じてください、私は試しました。)
ドキュメント
同様-mフラグのドキュメント言います:
名前付きモジュールのsys.pathを検索し、その内容を__main__
モジュールとして実行します。
そして
-cオプションと同様に、現在のディレクトリはsys.pathの先頭に追加されます。
そう
python -m pdb
とほぼ同等
python /usr/lib/python3.5/pdb.py
(現在のディレクトリにpdb.pyというパッケージまたはスクリプトがない場合)
説明:
動作は「意図的にスクリプトに似ている」ようになります。
多くの標準ライブラリモジュールには、実行時にスクリプトとして呼び出されるコードが含まれています。例はtimeitモジュールです:
一部のpythonコードはモジュールとして実行することを目的としています(この例はコマンドラインオプションのdocの例よりも優れていると思います)
$ python -m timeit '"-".join(str(n) for n in range(100))'
10000 loops, best of 3: 40.3 usec per loop
$ python -m timeit '"-".join([str(n) for n in range(100)])'
10000 loops, best of 3: 33.4 usec per loop
$ python -m timeit '"-".join(map(str, range(100)))'
10000 loops, best of 3: 25.2 usec per loop
そしてPython 2.4のリリースノートのハイライトから:
-mコマンドラインオプション-python -m modulenameは、標準ライブラリでモジュールを検索して呼び出します。たとえば、python -m pdb
と同等ですpython /usr/lib/python2.4/pdb.py
フォローアップ質問
また、David BeazleyのPython Essential Referenceは、「-mオプション__main__
は、メインスクリプトの実行前にモジュール内で実行されるスクリプトとしてライブラリモジュールを実行する」と説明しています。
これは、importステートメントで検索できるモジュールは、プログラムのエントリポイントとして実行できることを意味しますif __name__ == '__main__':
。通常、コードブロックの最後にが付いている場合。
-m
現在のディレクトリをパスに追加せずに:
ここの他の場所でのコメントは言う:
-mオプションが現在のディレクトリをsys.pathに追加することも、明らかにセキュリティ上の問題です(参照:プリロード攻撃)。この動作は、Windowsのライブラリ検索順序と似ています(最近強化される前)。Pythonがこのトレンドに従わず、追加を無効にする簡単な方法を提供していないのは残念です。sys.path
まあ、これは考えられる問題を示しています-(Windowsでは引用符を削除してください):
echo "import sys; print(sys.version)" > pdb.py
python -m pdb
3.5.2 |Anaconda 4.1.1 (64-bit)| (default, Jul 5 2016, 11:41:13) [MSC v.1900 64 bit (AMD64)]
-I
フラグを使用して、これを本番環境用にロックダウンします(バージョン3.4の新機能):
python -Im pdb
usage: pdb.py [-c command] ... pyfile [arg] ...
etc...
ドキュメントから:
-I
Pythonを分離モードで実行します。これは、-Eおよび-sも意味します。分離モードでは、sys.pathにはスクリプトのディレクトリもユーザーのサイトパッケージディレクトリも含まれていません。PYTHON *環境変数もすべて無視されます。ユーザーが悪意のあるコードを挿入できないように、さらに制限が課される場合があります。
何をし__package__
ますか?
これは明示的な相対インポートを可能にしますが、この質問に特に密接に関係するものではありません-この回答をここで参照してください:Pythonの "__package__"属性の目的は何ですか?
PYTHONPATH=test python -m foo.bar
どういう意味ですか?詳しく説明していただけますか?