Python で __name__=='__main__' の場合を理解する

公開: 2022-08-12

このガイドでは、Python での if __name__ == '__main__'の機能と重要性を理解します。

さまざまなモジュールを含む Python コードベースにざっと目を通したことはありますか?

はいの場合、1 つ以上のモジュールで if __name__ == '__main__' conditional に遭遇した可能性があります。 次の数分間で、上記の条件が何を意味するのかをわかりやすく説明し、それが役立つ例を見ていきます。

さぁ、始めよう!

Python における __name__ の意味は何ですか?

Python における __name__ の意味は何ですか?

Python では、モジュールは、関数定義、評価される一連の式などを含む.pyファイルです。 たとえば、hello_world.py という名前のファイルがある場合、これを hello_world.py ファイルまたはhello_worldモジュールと呼びます。

Python モジュールを実行すると、Python インタープリターは実行前にいくつかの特別な変数の値を設定します__name__はその 1 つです。 __name__の重要性を理解する鍵は、Python でインポートがどのように機能するかを理解することです。

このセクションのコードはこちらからダウンロードしてください。

example-1フォルダーに移動します。 ファイルmodule1.pyがあります。 __name__変数は、現在のモジュールの名前空間にあります。

このモジュールは、 __name__変数の値が続く行を出力します。

 # example-1/module1.py print("This is module1.") print(f"The __name__ variable of module 1 is: {__name__}.")

それでは、コマンド ラインからmodule1を実行してみましょう。

 $ python module1.py

出力では、 __name__変数が__main__に設定されていることがわかります。

 This is module1. The __name__ variable of module 1 is: __main__.

Python でのモジュールのインポート

Python モジュールの実行に加えて、現在のモジュール内の別の Python モジュールの機能を使用したい場合があります。 Python はimportsによってこれを容易にします。

インポートを使用すると、現在のモジュールのスコープにインポートすることで、別のモジュールの機能を再利用できます。コードを書き直す必要はありません。

Python でのモジュールのインポート

module2.pyファイルには次のものが含まれています。 内部にmodule1をインポートしました。 module2

 # example-1/module2.py import module1 # module1 is imported print(f"This is module2") print(f"The __name__ variable of module2 is: {__name__}.")

module2.pyを実行し、出力を観察します。

 $ python module2.py

以下の出力では:

  • module2 内にインポートすると、 module1が内部で実行され、対応する出力が出力されることがmodule2ます。
  • しかし、今回は __name__ 変数は __main__ ではなくmodule1です。
  • module2を直接実行したため、モジュールに対応する __name__ 変数は __main__ になりました。
 Output This is module1. The __name__ variable of module 1 is: module1. This is module2 The __name__ variable of module2 is: __main__.

重要なアイデア:

– モジュールが直接実行される場合、その __name__ 変数は__main__と同じに設定されます。

– モジュールが別のモジュール内にインポートされた場合、その __name__ はモジュールの名前に設定されます。

Python での if __name__=='__main__' の例

Python での if __name__=='__main__' の例

このセクションでは、if __name__ == '__main__' 条件の実用的な使用例を見ていきます。 単純な関数を定義してから、単体テストを作成して、関数が期待どおりに機能しているかどうかを確認します。

コードをダウンロードして、手順に従ってください。

このセクションのコードは、 example-2フォルダーにあります。

ここで、 add.pyは、関数add_ab()の定義を含む Python ファイルです。関数add_ab()は、任意の 2 つの数値を取り、それらの合計を返します。

 # example-2/add.py def add_ab(a,b): return a + b
単体テスト

Python のunittestモジュールを使用して関数add_ab()をテストします。

Python 関数のテスト ケースの作成

test_addモジュールの内容を含む以下のコード スニペットを見てください。

 # example-2/test_add.py import unittest from add import add_ab class TestAdd(unittest.TestCase): def test_add_23(self): self.assertEqual(add_ab(2,3), 5) def test_add_19(self): self.assertEqual(add_ab(1,9), 10) def test_add_1_minus7(self): self.assertEqual(add_ab(1,-7), -6)

上記のコードは次のことを行います。

  • Python の組み込みunittestモジュールをインポートします
  • addモジュールから関数add_ab()をインポートします。
  • テスト クラスTestAddと一連のテスト ケースをテスト クラス内のメソッドとして定義します。

コードの単体テストを設定するには、最初にunittest.TestCaseから継承するテスト クラスを定義する必要があります。 すべてのテスト ケースは、クラス内のメソッドとして指定する必要があり、 test_で開始する必要があります。

: メソッドにtest_<some-descriptive-name>を付けないと、対応するテストが検出されないため、実行されないことがわかります。

それでは、ターミナルからtest_addモジュールを実行してみましょう。

 $ python test_add.py

出力がなく、どのテストも実行されていないことがわかります。

これはなぜですか?

これは、単体テストを実行するには、次のコマンドを使用して、 test_add.pyの実行中にunittestをメイン モジュールとして実行する必要があるためです。

 $ python -m unittest test_add.py

上記の詳細コマンドを実行すると、3 つのテストすべてが正常に実行されたことがわかります。

 Output ... ---------------------------------------------------------------------- Ran 3 tests in 0.000s OK

ただし、このモジュールtest_addを実行するときにテストを実行すると便利ですよね? 次のセクションでその方法を学びましょう。

if __name__ == '__main__' を使用して unittest をメイン モジュールとして実行する

unittest をメイン モジュールとして実行する

モジュールを直接実行するときにすべての単体テストを実行したい場合は、条件を追加できます。

 # example-2/test_add.py import unittest from add import add_ab class TestAdd(unittest.TestCase): def test_add_23(self): self.assertEqual(add_ab(2,3), 5) def test_add_19(self): self.assertEqual(add_ab(1,9), 10) def test_add_1_minus7(self): self.assertEqual(add_ab(1,-7), -6) # Run unittest as the main module if __name__ == '__main__': unittest.main()

上記のコード スニペットの条件は、Python インタープリターに次のように伝えます。このモジュールが直接実行される場合は、内部のコードを実行します。 unittest.main() .

上記の 2 行のコードを追加した後、 test_addモジュールを実行できます。

 $ python test_add.py

️ test add module を直接実行すると、定義した 3 つのテストすべてが実行されるようになりました。

 Output ... ---------------------------------------------------------------------- Ran 3 tests in 0.000s OK

上記の出力 OK は、すべてのテストが正常に実行されたことを示します。 3 つのドットは、3 つのテストが実行され、すべて合格したことを示します。

ここで、予想される戻り値test_add_1_minus7を 8 に変更します。この場合、関数は – 6 を返すため、失敗したテストが 1 つあるはずです。

 def test_add_1_minus7(self): self.assertEqual(add_ab(1,-7), 8)

以下の出力に見られるように、 .F. 、3 つのテストのうち、そのうちの 1 つ (2 番目のテスト) が失敗したパターンを示し、トレースバックで、– 6 != 8 を示すAssertionErrorを取得します。

 Output .F. ====================================================================== FAIL: test_add_1_minus7 (__main__.TestAdd) ---------------------------------------------------------------------- Traceback (most recent call last): File "test_add.py", line 12, in test_add_1_minus7 self.assertEqual(add_ab(1,-7), 8) AssertionError: -6 != 8 ---------------------------------------------------------------------- Ran 3 tests in 0.021s FAILED (failures=1)

注意すべき重要な点の 1 つは、テストがテスト クラスで指定されている順序と同じ順序で実行されるとは限らないことです。 上記の例では、 test_add_1_minus7がテスト クラスの 3 番目のメソッドとして定義されていますが、対応するテストは 2 番目に実行されています。

まとめ

このチュートリアルが、Python で if __name__ == '__main__' 条件がどのように機能するかを理解するのに役立つことを願っています。

重要なポイントを簡単に要約すると、次のようになります。

  • Python インタープリターは、Python スクリプトを実行する前に__name__変数を設定します。
  • モジュールを直接実行すると、 __name__の値は__main__になります。
  • モジュールを別の Python スクリプト内にインポートすると、 __name__の値がモジュール名になります。
  • if __name__ == '__main__'を使用して、実行を制御し、直接およびインポートされた実行中に実行されるモジュールの部分をそれぞれ制御できます。

次に、Python セットに関するこの詳細なガイドを確認してください。 ハッピーラーニング!