インポート時にPythonがモジュールを実行するのはなぜですか、またどのように停止するのですか?


173

私が作成している2つの方法のいずれかで実行できるPythonプログラムがあります。1つ目は、ユーザーにわかりやすい方法で入力を求める「python main.py」を呼び出し、プログラムを通じてユーザー入力を実行することです。もう1つの方法は、「python batch.py -file-」を呼び出すことです。これにより、フレンドリーな入力の収集がすべて渡され、ファイル全体の価値のある入力がプログラムを通じて1回で実行されます。

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

import main

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

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

回答:


251

これは、Pythonが機能するための方法です。宣言などのキーワードは宣言classdefはありません。代わりに、それらは実行される実際のライブステートメントです。それらが実行されなかった場合、モジュールは空になります。

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

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

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

参照してくださいとは何if __name__ == "__main__"のために?

importただし、ed されるモジュールのソース管理が必要です。

ハッピーコーディング。


1
確認のために、「ここで 'import'を介して呼び出されない場合にのみ実行されるもの」というコメントは、コマンドがmain()の下に記述されることを意味しますよね?またはそれは問題ではありませんか?
ゴールドネーム2017

@Goldname ifステートメント内のコードはインポート時に実行されませんが、メイン関数自体が定義されており、インポートを介しても使用できます。このモジュールは、実行時にmain関数を実行するだけで、インポートされた場合は実行しません。それはすべてあなたが何をしたいかに依存します。main内の他の場所でコマンドが必要ない場合は、必ずif内に記述してください。しかし、私にはそれはきれいに見えます。
Felix

51

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

インポート時にモジュール内のコードが実行されないようにするには、直接実行した場合のみ、次のようにして保護できますif

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

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

def main():
    print "Hello World"

if __name__ == "__main__":
    main()

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

import foo

...

foo.main()

12

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

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

4

残念ながらそうではありません。これはインポート構文の動作方法の一部であり、そのようにすることが重要defです。Pythonがインポートを実行しなかった場合、実際には何かが実行されることを覚えておいてください。

ただし、おそらくファイルにアクセスできるため、エラーの原因を調べて確認できる場合があります。エラーの発生を防ぐために環境を変更できる可能性があります。


1
注:エラーを防ぐために環境を変更する方法がない場合は、別のモジュールを使用する必要があるかもしれません
cwallenpoole

4

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

if __name__ == '__main__':
  main()

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


3

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


2

"main.py"は次のように書くことができます:

#!/usr/bin/env python

__all__=["somevar", "do_something"]

somevar=""

def do_something():
    pass #blahblah

if __name__=="__main__":
    do_something()

-1

importコードを実行しないと使用できませんが、変数を入力する非常に迅速な方法があります。を使用してnumpy.savez、変数をnumpy配列として.npzファイルに格納します。その後、を使用して変数をロードできますnumpy.load

scipyのドキュメントで詳細な説明参照してください

これは、変数や変数の配列の場合にのみ当てはまり、メソッドなどには当てはまりません。


-4

main.pyから必要な関数をインポートするだけですか?そう、

from main import SomeFunction

main.pyの関数と同じ名前をbatch.py​​で指定した可能性があります。main.pyをインポートすると、プログラムはbatch.py​​関数ではなくmain.py関数を実行します。上記を実行すると、それが修正されます。私は願います。


少なくともWindowsではそうではありません。
マルティン・コル

2
import mainmainから現在の名前空間にすべてをインポートするわけではありません。main現在のネームスペースに単一のシンボルを追加するだけなので、衝突は発生しません。
レムラム2013年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.