web-dev-qa-db-ja.com

モジュールをインポートするときにPythonがモジュールを実行しているのはなぜですか、どうすれば停止できますか?

私が構築しているPythonプログラムは2つの方法のいずれかで実行できます。最初の方法は、ユーザーにわかりやすい方法で入力を求める「python main.py」を呼び出してから、プログラムを介したユーザー入力。もう1つの方法は、 "python batch.py​​ -file-"を呼び出すことです。これにより、すべての友好的な入力収集が渡され、プログラム全体でファイル全体の入力が一度に実行されます。

問題は、「batch.py​​」を実行すると、「main.py」からいくつかの変数/メソッド/などがインポートされ、このコードを実行すると:

import main

プログラムの最初の行では、「main.py」のコードを実行しようとするため、すぐにエラーになります。

Pythonがインポートしている「メイン」モジュールに含まれるコードの実行を停止するにはどうすればよいですか?

142
Dasmowenator

これはPythonの動作方法だからです-classdefなどのキーワードはではなく宣言です。代わりに、実行される本物のライブステートメントです。それらが実行されなかった場合、モジュールは空になります。

とにかく、慣用的なアプローチは次のとおりです。

# stuff to run always here such as class/def
def main():
    pass

if __== "__main__":
   # stuff only to run when not called via 'import' here
   main()

if __== "__main__"とは? を参照してください

ただし、importedであるモジュールのソース管理が必要です。

ハッピーコーディング。

211
user166390

Pythonの動作方法により、モジュールをインポートするときにモジュールを実行する必要があります。

インポート時にモジュール内のコードが実行されるのを防ぐために、直接実行する場合にのみ、次のifで保護できます。

if __== "__main__":
    # this won't be run when imported

このコードをmain()メソッドに入れて、ファイルを直接実行するか、モジュールをインポートしてmain()を呼び出すことができます。たとえば、これがファイルfoo.pyにあると仮定します。

def main():
    print "Hello World"

if __== "__main__":
    main()

このプログラムは、python foo.pyを実行するか、別のPythonスクリプトから実行できます。

import foo

...

foo.main()
46
Jeremy Banks

if __== '__main__'イディオムを使用します-__name__は、モジュールがスクリプトとして実行されている場合は'__main__'、インポートされている場合はモジュール名の値を持つ特別な変数です。だからあなたは次のようなことをするだろう

# imports
# class/function definitions
if __== '__main__':
    # code here will only run when you invoke 'python main.py'
11
Ismail Badawi

残念ながら、あなたはそうしません。それはインポート構文の仕組みの一部であり、そうすることは重要です-defは実際に実行されるものであり、Pythonがインポートを実行しなかった場合、関数なしでスタックすることになります。

ただし、おそらくファイルにアクセスできるため、エラーの原因を調べて確認できる場合があります。エラーが発生しないように環境を変更することが可能かもしれません。

4
cwallenpoole

関数内にコードを配置すると、関数を呼び出すまで実行されません。 main.pyにメイン関数が必要です。次のステートメントを使用して:

if __== '__main__':
  main()

次に、python main.pyを呼び出すと、main()関数が実行されます。 main.pyをインポートすると、インポートされません。また、わかりやすくするために、おそらくmain.pyを別の名前に変更する必要があります。

4
Matt

次のように「main.py」を書くことができます。

#!/usr/bin/env python

__all__=["somevar", "do_something"]

somevar=""

def do_something():
    pass #blahblah

if __name__=="__main__":
    do_something()
2
hgoldfish

Python拡張の提案がありました PEP 299if __== '__main__':イディオムをdef __main__:に置き換えることを目指していましたが、拒否されました。 if __= '__main__':を使用する際に留意すべきことを知ることは、まだ良い読み物です。

1
Paul Tobias