2011-12-01 6 views
8

私は、次のすべてを読んだ後、答えを見つけることができませんでした:
:Pythonインタプリタの-mオプション pythonスクリプトがインタープリタの-mオプションを使って実行されたかどうかを知る方法?

理論的根拠の

  • PEP 338 Executing modules as scripts
  • runpy標準モジュールのdocumentation
  • descriptionを相対インポートを使用するテストスクリプトはなしで実行されていますオプション標準的なトレースバックをユーザに残すのではなく、警告メッセージを出力してValueError: Attempted relative import in non-package例外につなげることができました。これを知ることなしに私はこの例外をキャッチすることができ、であることを示唆し、-mオプションの欠如がエラーの原因になる可能性があります。

+1

何が必要ですか?このニーズが明らかになったいくつかの例やテストケースを教えてください。 – jsalonen

答えて

2

別の観察は__package__がに設定されていることです-mを使用しているときに直接スクリプトを実行すると(パッケージがパッケージに含まれていない場合は空の文字列を使用するため、Noneとは異なります)、スクリプトを直接実行するときに発生します。

+1

ニース! ** PEP 366メインモジュールの明示的な相対的なインポート(http://www.python.org/dev/peps/pep-0366/)では、これは**必須です**だけではありません。 –

3

免責事項:これは単なる見解ですが、ドキュメントでは見たことがないので、実装に依存している可能性があり、異なるPythonバージョン間で一貫性がない可能性があります。

私はあなたのスクリプトの先頭になるよう、__loader__と呼ばれる変数は、名前空間に追加され-mオプションを使用してスクリプトを呼び出すときにその変数の存在を確認できたことに気づいた:

if '__loader__' in globals(): 
    # called with -m 

のためにあなたは__loader__pkgutil.ImpLoaderのインスタンスであるかどうかを確認することができ、いくつかの余分な安全性:

if '__loader__' in globals() and __loader__.__class__.__name__ == 'ImpLoader': 
+0

**これは** runpyモジュールのドキュメントにあります。 *特別なグローバル変数 '__name__'、' __file__'、 '__loader__'、' __package__'はモジュールコードが実行される前にグローバルディクショナリにセットされます(これは最小限の変数です。他の変数は暗黙的にインタプリタの実装の詳細)*しかし、 '__loader__'は一般的なもので、いつ他のものを設定するのかはわかりません。 –

+1

+1これは完全に合理的な解決策です。 –

+0

@RaymondHettingerこの状況で本当に**ユニークな**グローバル変数が設定されている理由はありますか? –