Verstehen, ob __name__ == ‚__main__‘ in Python

Das Mysterium von if __name__ == ‚__main__‘ in Python gelüftet

Dieser Artikel beleuchtet die Funktionalität und Wichtigkeit von if __name__ == '__main__' in der Programmiersprache Python.

Sind Sie in Ihren Python-Projekten schon einmal auf Code gestoßen, der aus mehreren Modulen besteht?

Wenn dies der Fall ist, sind Sie wahrscheinlich schon auf die Bedingung if __name__ == '__main__' gestoßen. Im Folgenden werden wir die Bedeutung dieser Anweisung erklären und ein Anwendungsbeispiel betrachten.

Legen wir los!

Was bedeutet __name__ in Python?

In Python ist ein Modul eine .py-Datei, die Funktionsdefinitionen, Anweisungen und andere Elemente enthält. Wenn wir beispielsweise eine Datei namens hello_world.py haben, bezeichnen wir diese als Modul hello_world.

Wenn ein Python-Modul ausgeführt wird, legt der Interpreter vor der Ausführung einige spezielle Variablen fest, darunter __name__. Um die Bedeutung von __name__ zu verstehen, ist es wichtig, die Funktionsweise von Imports in Python zu kennen.

📁 Laden Sie den Code für diesen Abschnitt hier herunter.

Wechseln Sie zum Ordner example-1. Dort befindet sich die Datei module1.py. Die Variable __name__ ist im Namensraum des aktuellen Moduls definiert.

Dieses Modul gibt eine Zeile und den Wert der Variablen __name__ aus.

  # example-1/module1.py
  print("Dies ist Modul1.")
  print(f"Die __name__ Variable von Modul 1 ist: {__name__}.")
  

Führen wir module1 nun über die Kommandozeile aus.

  $ python module1.py
  

Die Ausgabe zeigt, dass die Variable __name__ den Wert __main__ hat.

  Dies ist Modul1.
  Die __name__ Variable von Modul 1 ist: __main__.
  

Importieren von Modulen in Python

Neben der direkten Ausführung von Modulen kann es vorkommen, dass Sie Funktionen aus einem anderen Modul im aktuellen Modul verwenden möchten. Python ermöglicht dies durch Imports.

Imports erlauben es Ihnen, Funktionen aus einem anderen Modul wiederzuverwenden, ohne den Code neu schreiben zu müssen. Dies geschieht, indem das Modul in den Gültigkeitsbereich des aktuellen Moduls eingefügt wird.

Die Datei module2.py enthält den folgenden Code: Hier wurde module1 importiert.

  # example-1/module2.py
  
  import module1 # module1 wurde importiert
  
  print(f"Dies ist Modul2")
  print(f"Die __name__ Variable von Modul2 ist: {__name__}.")
  

Wir führen module2.py aus und betrachten die Ausgabe:

  $ python module2.py
  

Die Ausgabe zeigt:

  • Dass module1 bei der Importierung in module2 ausgeführt wird und seine entsprechende Ausgabe erzeugt.
  • Dieses Mal ist die Variable __name__ nicht __main__, sondern module1.
  • Da module2 direkt ausgeführt wird, hat seine Variable __name__ den Wert __main__.
  Ausgabe:
  
  Dies ist Modul1.
  Die __name__ Variable von Modul 1 ist: module1.
  Dies ist Modul2
  Die __name__ Variable von Modul2 ist: __main__.
  

💡 Kernaussage:

– Wenn ein Modul direkt ausgeführt wird, wird seine Variable __name__ auf __main__ gesetzt.

– Wenn ein Modul in ein anderes Modul importiert wird, ist der Wert von __name__ der Modulname.

Anwendungsbeispiel für if __name__ == '__main__' in Python

Dieser Abschnitt zeigt einen praktischen Anwendungsfall für die Bedingung if __name__ == '__main__'. Wir definieren eine einfache Funktion und schreiben dann Unit-Tests, um die korrekte Funktionsweise zu überprüfen.

📁 Laden Sie den Code herunter und folgen Sie dem Beispiel.

Der Code für diesen Abschnitt befindet sich im Ordner example-2.

Hier ist add.py eine Python-Datei, die die Definition der Funktion add_ab() enthält. Die Funktion add_ab() nimmt zwei Zahlen als Argumente entgegen und gibt ihre Summe zurück.

  # example-2/add.py
  
  def add_ab(a,b):
      return a + b
  

Wir verwenden das unittest-Modul von Python, um die Funktion add_ab() zu testen.

Erstellen von Testfällen für eine Python-Funktion

Hier ist der Inhalt des Moduls 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)
    

Der obige Code macht Folgendes:

  • Importiert das integrierte unittest Modul von Python
  • Importiert die Funktion add_ab() aus dem Modul add
  • Definiert die Testklasse TestAdd und eine Reihe von Testfällen als Methoden innerhalb dieser Klasse

Um Unit-Tests für Ihren Code einzurichten, sollten Sie zunächst eine Testklasse definieren, die von unittest.TestCase erbt. Alle Testfälle sollten als Methoden innerhalb der Klasse angegeben werden und mit test_ beginnen.

Hinweis: Wenn Sie die Methoden nicht mit test_ benennen, werden die entsprechenden Tests nicht erkannt und daher auch nicht ausgeführt.

Versuchen wir nun, das Modul test_add über die Kommandozeile auszuführen:

  $ python test_add.py
  

Sie werden feststellen, dass keine Ausgabe erfolgt und keiner der Tests ausgeführt wurde.

Warum ist das so?🤔

Das liegt daran, dass zur Ausführung von Unit-Tests unittest als Hauptmodul ausgeführt werden muss, während test_add.py mit dem folgenden Befehl aufgerufen wird:

  $ python -m unittest test_add.py
  

Nach Ausführung des obigen Befehls werden alle drei Tests erfolgreich ausgeführt.

  Ausgabe:
  ...
  ----------------------------------------------------------------------
  Ran 3 tests in 0.000s
  
  OK
  

Es wäre jedoch praktischer, wenn die Tests ausgeführt würden, wenn das Modul test_add direkt aufgerufen wird, nicht wahr? Wir werden im nächsten Abschnitt sehen, wie das funktioniert.

Verwendung von if __name__ == '__main__' zur Ausführung von unittest als Hauptmodul

Wenn Sie alle Unit-Tests ausführen möchten, sobald das Modul direkt aufgerufen wird, können Sie die Bedingung hinzufügen.

  # 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)
  
  # Führe unittest als Hauptmodul aus
  if __name__ == '__main__':
          unittest.main()
  

Die Bedingung im Code-Snippet weist den Python-Interpreter an: Wenn dieses Modul direkt ausgeführt wird, dann führe den enthaltenen Code unittest.main() aus.

Sie können das Modul test_add ausführen, nachdem die obigen zwei Zeilen hinzugefügt wurden.

  $ python test_add.py
  

▶️ Durch die direkte Ausführung des Moduls test_add werden nun alle drei definierten Tests durchgeführt.

  Ausgabe:
  ...
  ----------------------------------------------------------------------
  Ran 3 tests in 0.000s
  
  OK
  

Die Ausgabe OK zeigt an, dass alle Tests erfolgreich waren. Die drei Punkte ... bedeuten, dass drei Tests ausgeführt und alle bestanden wurden.

Ändern wir nun den erwarteten Rückgabewert von test_add_1_minus7 auf 8. Da die Funktion -6 zurückgibt, sollte ein Test fehlschlagen.

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

Wie in der folgenden Ausgabe zu sehen ist, erhalten wir .F. als Ergebnis der drei Tests, wobei einer fehlschlägt (der zweite Test) und im Traceback ein AssertionError mit der Meldung -6 != 8 ausgegeben wird.

  Ausgabe:
  .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)
  

Es ist wichtig zu beachten, dass die Tests nicht unbedingt in der Reihenfolge ausgeführt werden, in der sie in der Testklasse angegeben sind. Im obigen Beispiel ist test_add_1_minus7 als dritte Methode in der Testklasse definiert, der entsprechende Test wurde jedoch als zweiter ausgeführt.

Zusammenfassung

Ich hoffe, dieser Artikel hat Ihnen geholfen, die Funktionsweise der Bedingung if __name__ == '__main__' in Python zu verstehen.

Hier ist eine kurze Zusammenfassung der wichtigsten Punkte:

  • Der Python-Interpreter legt die Variable __name__ fest, bevor das Python-Skript ausgeführt wird.
  • Wenn Sie ein Modul direkt ausführen, ist der Wert von __name__ __main__.
  • Wenn Sie ein Modul in ein anderes Python-Skript importieren, ist der Wert von __name__ der Modulname.
  • Sie können if __name__ == '__main__' verwenden, um zu steuern, welche Teile des Moduls bei direkter bzw. importierter Ausführung ausgeführt werden.

Lesen Sie als Nächstes diese ausführliche Anleitung zu Python-Sets. Viel Spaß beim Lernen!🎉