Ga naar hoofdinhoud

if __name__ == "__main__" Python: Complete Explanation

Het blok if __name__ == "__main__" in Python laat je code definiëren die alleen wordt uitgevoerd wanneer het bestand direct als script wordt uitgevoerd, maar niet wanneer het als module in een ander script wordt geïmporteerd.
· 8 min lezen

Verken met AI

Het conditionele blok dat begint met if __name__ == "__main__" komt vaak voor in Python-code. Deze regel kan cryptisch lijken, en veel beginners gebruiken hem zonder te weten wat hij doet of of ze hem zouden moeten gebruiken. Programmeurs die uit andere talen komen, kunnen deze uitdrukking ook verkeerd begrijpen en overmatig gebruiken.

Deze tutorial duikt in de betekenis van Python’s if__name__ == "__main__"-idioom en laat zien hoe en wanneer je het gebruikt.

Begrijpen van __name__ en "__main__"

Het idioom if __name__ == "__main__" is een if-statement dat op gelijkheid controleert.

De eerste operand links van de gelijkheidsoperator == is de attribuut __name__. Python-namen met dubbele underscores aan het begin en einde zijn speciale identifiers. Elk module heeft een __name__-attribuut. Python zet deze variabele op de modulenaam, die door het import-systeem van Python wordt gebruikt om elke module uniek te identificeren.

Als de module zich echter in de top-level code-omgeving bevindt, wat betekent dat het de module is die als ingangspunt voor het programma wordt gebruikt, zet Python het attribuut __name__ op de string "__main__".

Laten we wat voorbeelden bekijken. We maken een script met de naam exploring_name_main.py:

# exploring_name_main.py
import random
print(__name__)
print(random.__name__)

Dit script kun je direct uitvoeren met de volgende opdracht in de terminal:

$ python exploring_name_main.py
__main__
random

Het script exploring_name_main.py bevindt zich in de top-level code-omgeving omdat het het ingangspunt van het programma is. Daarom krijgt de variabele __name__ de waarde "__main__".

De module random daarentegen wordt geïmporteerd en bevindt zich niet in de top-level code-omgeving. Het __name__-attribuut krijgt de modulenaam.

Vervolgens maken we een nieuw script met de naam more_exploration.py, dat het eerste script importeert:

# more_exploration.py
import exploring_name_main

Voer dit script uit met de volgende opdracht in de terminal:

$ python more_exploration.py
exploring_name_main
random

De code van een module wordt uitgevoerd wanneer de module wordt geïmporteerd. Daarom toont het uitvoeren van more_exploration.py de uitvoer van de twee print()-aanroepen in exploring_name_main.py. Omdat exploring_name_main.py niet langer het ingangspunt van het programma is, wordt het __name__-attribuut ingesteld op de scriptnaam in plaats van op "__main__".

Het if __name__ == "__main__"-conditionele blok

Met de variabele __name__ kun je bepalen of een module het hoofd-ingangspunt van een programma is. Daarom kan een module code bevatten die alleen wordt uitgevoerd wanneer deze direct als script wordt gedraaid, maar niet wanneer deze wordt geïmporteerd. Alle code die alleen moet worden uitgevoerd wanneer het script direct wordt uitgevoerd, plaats je in het conditionele blok if __name__ == "__main__":

# exploring_name_main.py
import random
print(__name__)
print(random.__name__)
number = random.randint(1, 10)
if __name__ == "__main__":
    print("This script is in the top-level code environment")
    print(f"The number is {number}")

De code in exploring_name_main.py bevat nu een if __name__ == "__main__"-conditioneel blok. Laten we kijken of dit verschil maakt wanneer we het script uitvoeren:

$ python exploring_name_main.py
__main__
random
This script is in the top-level code environment
The number is 10

Wanneer het script direct wordt uitgevoerd, krijgt de variabele __name__ de waarde "__main__". Daarom evalueert de voorwaarde in de if-statement als True en voert Python de code in het if-blok uit.

Wanneer de module echter wordt geïmporteerd, wordt __name__ ingesteld op de modulenaam en voert het programma het if-blok niet uit. Onthoud dat het script more_exploration.py exploring_name_main importeert:

$  python more_exploration.py
exploring_name_main
random

Het programma roept de functies print() in exploring_name_main.py niet aan. Ze staan in het conditionele blok dat niet wordt uitgevoerd omdat __name__ niet gelijk is aan "__main__".

Best practices en tips bij het gebruik van Python’s if __name__ == "__main__"

Python’s if __name__ == "__main__"-idioom gebruik je wanneer code alleen moet worden uitgevoerd als een bestand als script wordt gedraaid en niet wanneer het als module wordt geïmporteerd. Het onderscheid tussen de termen script en module zit alleen in hoe het bestand wordt gebruikt. Beide termen verwijzen naar bestanden met de extensie .py.

Een veelvoorkomend usecase is wanneer een script variabelen, functies en klassen heeft die in andere programma’s gebruikt kunnen worden. Hier is een voorbeeld met een script genaamd shapes.py:

# shapes.py
import math
def find_area_of_circle(radius):
    return math.pi * radius ** 2
def find_area_of_rectangle(width, height):
    return width * height
if __name__ == "__main__":
    shape = int(input("Enter 1 for circle, 2 for rectangle: "))
    if shape == 1:
        radius = int(input("Enter radius: "))
        print(f"The area of the circle is {find_area_of_circle(radius)}")
    elif shape == 2:
        width = int(input("Enter width: "))
        height = int(input("Enter height: "))
        print(f"The area of the rectangle is {find_area_of_rectangle(width, height)}")
Enter 1 for circle, 2 for rectangle: 2
Enter width: 10
Enter height: 20
The area of the rectangle is 200

Deze code heeft het if __name__ == "__main__"-idioom niet nodig als de bedoeling is om het altijd als script te draaien. Maar door deze conditionele statement toe te voegen, kan de code als module worden geïmporteerd zonder de regels in het if-blok uit te voeren. Bekijk een ander script met de naam more_shapes.py:

# more_shapes.py
import shapes
radius = 5
print(f"The area of the circle defined in 'more_shapes.py' is: "
      f"{shapes.find_area_of_circle(radius)}")
The area of the circle defined in 'more_shapes.py' is: 78.53981633974483

Dit nieuwe script, more_shapes.py, heeft toegang tot de functies die in shapes.py zijn gedefinieerd dankzij de import-instructie. De code in het if __name__ == "__main__"-blok in shapes.py wordt echter niet uitgevoerd. Zonder de if-statement in shapes.py zou alle code worden uitgevoerd wanneer de module wordt geïmporteerd.

Het gebruik van het if __name__ == "__main__"-blok voor gebruikersinvoer is een veelvoorkomend scenario. De gebruikersinvoer wordt overgeslagen als het bestand als module wordt geïmporteerd, maar wel uitgevoerd wanneer het direct als top-level code wordt gedraaid.

Een main()-functie gebruiken

Het is best practice om zo min mogelijk statements in het if __name__ == "__main__"-blok op te nemen; dat maakt de code leesbaarder. Een gangbare manier om dit te bereiken is een functie te maken die in het conditionele blok wordt aangeroepen. Vaak heet deze functie main(), maar elke functienaam is geldig:

# shapes.py
import math
def find_area_of_circle(radius):
    return math.pi * radius ** 2
def find_area_of_rectangle(width, height):
    return width * height
def main():
    shape = int(input("Enter 1 for circle, 2 for rectangle: "))
    if shape == 1:
        radius = int(input("Enter radius: "))
        print(f"The area of the circle is {find_area_of_circle(radius)}")
    elif shape == 2:
        width = int(input("Enter width: "))
        height = int(input("Enter height: "))
        print(f"The area of the rectangle is {find_area_of_rectangle(width, height)}")
       
if __name__ == "__main__":
    main()

De code in de main()-functie is dezelfde code die eerder direct in het if __name__ == "__main__"-blok stond.

In Python is de main()-functie, in tegenstelling tot sommige andere programmeertalen, niet vereist als het hoofd-ingangspunt van het programma. Het gebruik van main() en het if __name__ == "__main__"-idioom is dus optioneel en alleen nodig wanneer de code zowel als zelfstandig script als als module bedoeld is.

Een andere veelvoorkomende usecase voor Python’s if __name__ == "__main__" is om tests aan het script toe te voegen. De tests draaien wanneer het script direct wordt uitgevoerd, maar niet wanneer het vanuit een andere module wordt geïmporteerd. Hoewel deze aanpak geschikt is voor eenvoudige gevallen, is het beter om tests in een aparte, aan testen gewijde module op te nemen.

Conclusie

Python’s if __name__ == "__main__" is handig om code op te nemen die alleen wordt uitgevoerd wanneer een script direct wordt gedraaid, maar niet wanneer het wordt geïmporteerd. De Python-interpreter zet de variabele __name__ op de naam van de module als deze wordt geïmporteerd en op de string "__main__" als de module het hoofd-ingangspunt van het programma is.

In tegenstelling tot sommige andere programmeertalen zijn de main()-functie en het if __name__ == "__main__"-idioom geen vereisten om Python-code uit te voeren, maar een hulpmiddel dat de programmeur naar behoefte kan inzetten.

Stephen Gruppetta

Auteur

Stephen Gruppetta

Ik studeerde natuurkunde en wiskunde op bachelorniveau aan de Universiteit van Malta. Daarna verhuisde ik naar Londen en behaalde ik mijn PhD in natuurkunde aan Imperial College. Ik werkte aan nieuwe optische technieken om het menselijk netvlies in beeld te brengen. Nu richt ik me op schrijven over Python, communiceren over Python en lesgeven in Python.

Onderwerpen

Gerelateerd