-m オプション付きで Python コードを実行するかどうか [重複] 質問する

-m オプション付きで Python コードを実行するかどうか [重複] 質問する

Pythonインタープリタは-m モジュール「ライブラリモジュールを実行する」オプションモジュール「スクリプトとして」。

この Python コード a.py では:

if __name__ == "__main__":
    print __package__
    print __name__

私はテストpython -m aを受けて

"" <-- Empty String
__main__

一方、python a.py戻り値

None <-- None
__main__

私にとって、これら 2 つの呼び出しは、-m オプションで呼び出されたときに __package__ が None ではないことを除いて同じであるように見えます。

興味深いことに、 を使用すると、 python モジュールをコンパイルして a.pyc を取得するのとpython -m runpy a同じ結果が得られます。python -m a

これらの呼び出しの (実際的な) 違いは何ですか? それぞれに長所と短所はありますか?

また、David BeazleyのPython Essential Referenceでは次のように説明されています。-m オプションは、メインスクリプトの実行前に__main__ モジュール内で実行されるスクリプトとしてライブラリモジュールを実行します。"。 それはどういう意味ですか?

ベストアンサー1

使用すると-mコマンドラインフラグPythonはモジュールをインポートしますまたはパッケージフラグを使用しない場合は-m、指定したファイルは次のように実行されます。ただのスクリプト

パッケージを実行するときには、この区別が重要になります。次の 2 つには大きな違いがあります。

python foo/bar/baz.py

そして

python -m foo.bar.baz

後者の場合と同様に、がインポートされ、 を開始点としてfoo.bar相対インポートが正しく機能します。foo.bar

デモ:

$ mkdir -p test/foo/bar
$ touch test/foo/__init__.py
$ touch test/foo/bar/__init__.py
$ cat << EOF > test/foo/bar/baz.py 
> if __name__ == "__main__":
>     print __package__
>     print __name__
> 
> EOF
$ PYTHONPATH=test python test/foo/bar/baz.py 
None
__main__
$ PYTHONPATH=test python -m foo.bar.baz 
foo.bar
__main__

その結果、Pythonはスイッチを使用する際にパッケージを実際に考慮する必要があります-m。通常のスクリプトではなれパッケージなので__package__に設定されていますNone

しかし、パッケージまたはモジュールを実行すると内部パッケージには-m少なくとも可能性パッケージの内部にあるため、__package__変数は文字列値に設定されます。上記のデモでは に設定されていますが'foo.bar'、パッケージ内にないプレーンなモジュールの場合は空の文字列に設定されます。

については__main__ モジュールPython は、実行中のスクリプトを通常のモジュールと同じようにインポートします。グローバル名前空間を保持するために新しいモジュール オブジェクトが作成され、 に格納されますsys.modules['__main__']。これが__name__変数が参照するものであり、その構造のキーとなります。

パッケージの場合は、__main__.py内部にモジュールを作成し、実行時に実行することができますpython -m package_name。実際、これが唯一の方法です。できるパッケージをスクリプトとして実行します。

$ PYTHONPATH=test python -m foo.bar
python: No module named foo.bar.__main__; 'foo.bar' is a package and cannot be directly executed
$ cp test/foo/bar/baz.py test/foo/bar/__main__.py
$ PYTHONPATH=test python -m foo.bar
foo.bar
__main__

したがって、 で実行するためにパッケージに名前を付けると、Python はそのパッケージに含まれるモジュール-mを探し、それをスクリプトとして実行します。その名前は に設定され、モジュール オブジェクトは に格納されたままになります。__main__'__main__'sys.modules['__main__']

おすすめ記事