if __name__ == "__main__"
In questa lezione spiegheremo il funzionamento di una delle righe di codice più comuni e spesso incomprese nel mondo di Python: if __name__ == "__main__".
def main():
pass
def print_tre_volte(parola):
print(parola)
print(parola)
print(parola)
if __name__ == "__main__":
main()
Abbiamo l'attributo __name__, che qualora corrisponda alla stringa "__main__" innesca la chiamata alla funzione main(). A cosa serve questa clausola di controllo? E perché si trova così spesso?
Diamo anzitutto uno sguardo alla documentazione ufficiale. Come leggiamo, questa riga consente al nostro codice di capire se stia venendo eseguito come script a sé stante, o se è invece stato richiamato come modulo da un qualche programma per usare una o più delle sua varie funzioni e classi. Possiamo immaginarlo visivamente come una sorta di punto d'ingresso o porta d'accesso al nostro programma. I vantaggi di sapere in che modo il nostro codice sta venendo eseguito sono molteplici e li vedremo tra poco, ma prima è bene capire come fa esattamente a fare ciò.
Cosa succede se il file viene eseguito direttamente come script?
Quando Python esegue del codice assegna alcune variabili speciali, tra cui anche la variabile __name__. Python si rende conto se sta eseguendo questo script direttamente, ad esempio tramite VSCode o dalla shell di sistema:
python script_a.py
In questi casi l'istruzione if fa sì che venga assegnata alla variabile __name__ la stringa "__main__".
>>> print(__name__)
__main__
Quindi in questo caso la condizione di controllo risulta True e la funzione ad essere richiamata è main(), la funzione principale del programma che contiene le prime righe che vogliamo eseguire, ad esempio:
def main():
print("Prime righe da eseguire SOLO se lo script è stato lanciato 'come programma'")
print("Lanciato automaticamente se a __name__ è assegnato __main__ ")
Cosa succede se il file se viene importato come modulo in un altro file?
Se invece stiamo richiamando lo script come modulo da dentro a un altro programma, alla variabile __name__ verrà assegnato il nome dello script, quindi il nome del modulo:
# script_b
>>> import script_a
>>> print(script_a.__name__)
# output
script_a
Possiamo ora comodamente richiamare le funzioni del nostro script_a:
# script_b
>>> import script_a
>>> print(script_a.__name__)
# output
script_a
>>> script_a.print_tre_volte("asd")
# output
asd
asd
asd
Ed ecco quindi svelato il mistero del funzionamento! Tra i casi d'uso in cui questo può tornare utile, c'è la possibilità di continuare a sviluppare del codice che vogliamo testare dall'interno, lasciando comunque la possibilità ad altri programmatori di utilizzare il resto delle nostre funzioni.
def main():
print("Codice da testare.")
print("Prime righe da eseguire SOLO se lo script è stato lanciato 'come programma'")
print("Lanciato automaticamente se a __name__ è assegnato __main__ ")
def print_tre_volte(parola):
print(parola)
print(parola)
print(parola)
if __name__ == "__main__":
main()
# script_a:
Codice da testare.
Prime righe da eseguire SOLO se lo script è stato lanciato 'come programma'
Lanciato automaticamente se a __name__ è assegnato __main__
Quindi, per sintetizzare il tutto in una frase: utilizziamo if __name__ == "__main__" in tutti quei casi in cui vogliamo che il nostro codice possa avere un doppio comportamento e utilizzo, sia come programma che come modulo.
Happy Coding! :D