Die seltsamste Zeile in Python — entmystifiziert
Öffne fast jede Python-Datei, und du siehst irgendwann unten das hier:
if __name__ == "__main__":
main()
Es sieht nach magischem Boilerplate aus. Tatsächlich ist es ein sehr praktisches Feature, sobald du weißt, was es tut — und es existiert, weil Python keine Grenze zwischen „Skripten“ und „Bibliotheken“ zieht.
Der Aufbau: zwei Arten, eine Datei zu nutzen
Jede .py-Datei in Python kann auf zwei Arten genutzt werden:
- Als Skript — du startest sie direkt mit
python3 file.py. - Als Modul — eine andere Datei importiert sie mit
import file.
Die Sprache zwingt dich nicht zu einer Erklärung, welches du schreibst. Jede Datei kann am Ende beides sein.
Stell dir eine Datei math_helpers.py vor:
# math_helpers.py
def mean(values):
return sum(values) / len(values)
def median(values):
s = sorted(values)
mid = len(s) // 2
if len(s) % 2 == 0:
return (s[mid - 1] + s[mid]) / 2
return s[mid]
# Quick smoke test while developing
numbers = [3, 1, 4, 1, 5, 9, 2, 6]
print("mean:", mean(numbers))
print("median:", median(numbers))
Führst du die Datei direkt aus, gibt sie die Testausgabe aus — super. Aber macht eine andere Datei import math_helpers, laufen die print-Anweisungen während des Imports. Jede Nutzerin des Moduls sieht deine Entwickler-Kritzeleien. Weniger super.
Was __name__ ist
Jedes Python-Modul hat eine eingebaute Variable __name__. Python setzt sie automatisch:
- Wird die Datei importiert, ist
__name__der Import-Name des Moduls — im Beispiel"math_helpers". - Wird die Datei direkt ausgeführt, setzt Python
__name__auf den besonderen String"__main__".
Das gibt dir einen Weg zu erkennen, in welchem Modus du bist. Wickle den „nur Skript“-Code in eine Prüfung:
# math_helpers.py
def mean(values):
return sum(values) / len(values)
def median(values):
s = sorted(values)
mid = len(s) // 2
if len(s) % 2 == 0:
return (s[mid - 1] + s[mid]) / 2
return s[mid]
if __name__ == "__main__":
numbers = [3, 1, 4, 1, 5, 9, 2, 6]
print("mean:", mean(numbers))
print("median:", median(numbers))
Jetzt gibt python3 math_helpers.py die Testausgabe aus. Aber import math_helpers aus einer anderen Datei überspringt den Block komplett — die Funktionen sind verfügbar, und nichts Unerwünschtes läuft.
Der häufige Begleiter: eine main()-Funktion
Die meisten echten Skripte bekommen eine eigene main()-Funktion und halten den Guard-Block klein:
# process_orders.py
import sys
def load_orders(path):
with open(path) as f:
return [line.strip() for line in f if line.strip()]
def process(orders):
for order in orders:
print(f"Processing {order}")
def main():
if len(sys.argv) < 2:
print("Usage: python3 process_orders.py <file>")
sys.exit(1)
orders = load_orders(sys.argv[1])
process(orders)
if __name__ == "__main__":
main()
Warum der Aufwand mit einem main() statt die Logik direkt unter den if-Guard zu packen?
- Testbarkeit. Du kannst das Modul importieren und
main()(oder andere Helfer) aus Tests aufrufen. - Lokale Variablen. Alles in
main()Definierte ist eine lokale Variable, kein Modul-Level-Name. Das vermeidet zufällige Namenskollisionen und hält die öffentliche Modul-Oberfläche sauber. - Lesbarkeit. Der Guard-Block ist nur noch zwei Zeilen — ein klarer „Skript-Einstiegspunkt“ statt einem Haufen Logik.
Eine schnelle Demonstration
Das Verhalten kannst du direkt sehen:
Führst du das Snippet mit Python aus, gibt es __name__ is: __main__ und „wird als Skript ausgeführt“ aus. Würde eine andere Datei diese importieren, ginge dieselbe Prüfung in den anderen Zweig.
Wann du den Guard nicht brauchst
Viele Python-Dateien bekommen nie einen. Kurze Skripte, die nie jemand importieren würde, sind auch ohne okay:
# one_off_rename.py
import os
for name in os.listdir("."):
if name.endswith(".txt"):
os.rename(name, name.lower())
Das ist völlig in Ordnung. Du baust keine Bibliothek; das importiert niemand. Sobald aber wiederverwendbare Logik in einer Datei steckt — und du Seiteneffekt-Code daneben halten willst —, greif zum Guard.
Einstiegspunkte für installierte Pakete
Veröffentlichst du deinen Code als richtiges Paket, gibt es einen formelleren Mechanismus: entry_points in den Paket-Metadaten, die einen Befehl auf eine Funktion abbilden. Nutzer, die dein Paket installieren, bekommen einen Shell-Befehl, der die Funktion direkt aufruft. Aber für Skripte, die aus einem Ordner auf deinem Rechner laufen, ist der __main__-Guard das Standardwerkzeug.
Abschluss dieses Kapitels
Du hast jetzt:
- Funktionen, um deiner Logik Namen zu geben.
*args/**kwargsfür flexible Aufrufe.- Lambdas für Einweg-Funktionen.
- Dekoratoren und Type Hints, um Funktionen zu umhüllen und zu dokumentieren.
- Module, pip und virtuelle Umgebungen, um Code über Dateien und Projekte zu verteilen.
- Den
__main__-Guard, damit Skripte und Module koexistieren.
Als Nächstes: Klassen
Bisher hast du Funktionen meist mit simplen Daten gepaart — Dicts, Listen, Tupel. Das nächste Kapitel stellt Klassen vor, Pythons Art, Daten und Verhalten zusammenzuschnüren, und den Ort, an dem Konzepte wie self, __init__, Vererbung und Dataclasses leben.
Häufig gestellte Fragen
Was macht if __name__ == '__main__'?
if __name__ == '__main__'?Es führt den darunterliegenden Block nur aus, wenn die Datei direkt ausgeführt wird (nicht, wenn sie als Modul importiert wird). So kannst du eine .py-Datei schreiben, die sich als Skript starten oder wegen ihrer Funktionen und Klassen importieren lässt — ohne dass die Skript-Aktionen beim Import passieren.
Braucht Python eine main-Funktion?
Nein. Python-Dateien laufen automatisch von oben nach unten. Aber sobald eine Datei Logik enthält, die auch importierbar sein soll, wird der if __name__ == '__main__'-Guard wichtig — und den Einstieg in eine main()-Funktion zu packen ist eine häufige Begleitangewohnheit.
Was ist der Unterschied zwischen __name__ und __main__?
__name__ und __main__?__name__ ist eine spezielle Variable, die Python in jedem Modul setzt. Wird die Datei importiert, ist __name__ der Modulname (z. B. 'util'). Wird sie direkt ausgeführt, setzt Python __name__ auf den String '__main__'. Die if-Prüfung vergleicht beides.