Capire if __name__ == "__main__" con esempi
Cosa significa if __name__ == "__main__" in Python: differenza tra eseguire un file e importarlo, con esempi pratici su Windows, macOS e Linux.
Se hai mai copiato uno script Python da internet, o letto il codice di alcuni strumenti su ai riparo, avrai notato questa riga quasi sempre in fondo al file:
if __name__ == "__main__":
main()
Per chi è alle prime armi sembra una formula magica. Non lo è. È un meccanismo di controllo: Python distingue se stai lanciando il file direttamente oppure se lo stai importando in un altro file per riusarne le funzioni.
In questo articolo ti mostro cosa significa la sintassi, come si comporta __name__ e perché la «guardia» protegge da esecuzioni accidentali. Lo fai con due file minimi, dal terminale, su Windows, macOS e Linux.
ℹ️ Nota / Prerequisito
Serve Python installato e sapere aprire il terminale.
Letture opzionali: Terminale: comandi minimi, Struttura minima di un progetto Python.
Che cos’è __name__
In Python, __name__ non è un comando. È una variabile speciale (una stringa) che l’interprete crea e imposta ogni volta che legge un file sorgente.
Ha due underscore all’inizio e due alla fine. Questa convenzione (dunder, da double underscore) marca nomi speciali di sistema.
Il valore cambia a seconda di come il file viene caricato. Puoi verificarlo in un file vuoto con una sola riga: print(__name__).
Le due modalità: esecuzione vs importazione
Quando scrivi un file (es. script.py) puoi usarlo in due modi. Python rileva la scelta e imposta __name__ di conseguenza.
| Situazione | Valore tipico di __name__ |
Cosa succede |
|---|---|---|
Lanci il file da terminale (python script.py) |
"__main__" |
Sei nel punto d’ingresso del programma |
Lo importi (import script) |
"script" (nome del modulo) |
Carichi funzioni/classi; non sei «main» |
La condizione if __name__ == "__main__": è la guardia: esegui il blocco sotto solo se l’utente ha lanciato direttamente quel file; se lo sta solo importando, ignoralo.
Per vederlo in pratica, metti le mani sulla tastiera.
Lab A — Creare ed eseguire il file direttamente
Crea una cartella (es. test-python sul Desktop). Nell’editor crea saluta.py e incolla:
def genera_saluto(nome):
return f"Ciao, {nome}! Benvenuto."
print("1. Il file saluta.py è stato letto.")
print(f"2. In questo momento, __name__ vale: {__name__}")
if __name__ == "__main__":
print("3. La guardia è superata! Eseguo il codice principale.")
messaggio = genera_saluto("Alex")
print(messaggio)
Apri il terminale, entra nella cartella ed esegui.
Windows
cd %USERPROFILE%\Desktop\test-python
python saluta.py
macOS e Linux
cd ~/Desktop/test-python
python3 saluta.py
Output atteso:
1. Il file saluta.py è stato letto.
2. In questo momento, __name__ vale: __main__
3. La guardia è superata! Eseguo il codice principale.
Ciao, Alex! Benvenuto.
Cosa è successo?
Hai chiesto a Python di eseguire saluta.py: l’interprete ha assegnato a __name__ la stringa "__main__". La condizione è vera → il blocco rientrato gira e stampa il saluto.
Lab B — Importare da un altro file
Lascia saluta.py com’è. Nella stessa cartella crea usa_saluta.py:
import saluta
print("A. Sono dentro usa_saluta.py")
print(f"B. Qui dentro, il mio __name__ vale: {__name__}")
nuovo_messaggio = saluta.genera_saluto("Lettore")
print(nuovo_messaggio)
Esegui il secondo file (sempre dalla stessa cartella).
Windows
python usa_saluta.py
macOS e Linux
python3 usa_saluta.py
Output atteso:
1. Il file saluta.py è stato letto.
2. In questo momento, __name__ vale: saluta
A. Sono dentro usa_saluta.py
B. Qui dentro, il mio __name__ vale: __main__
Ciao, Lettore! Benvenuto.
Cosa è successo questa volta?
- Hai eseguito
usa_saluta.py→ per quel file__name__è"__main__". - All’
import saluta, Python leggesaluta.pydall’inizio alla fine. - Stampa le righe 1 e 2 di
saluta.py. - Differenza cruciale: mentre legge
saluta.py,__name__vale"saluta"(nome del file senza.py). if __name__ == "__main__":è falso → il blocco con «Ciao, Alex!» non parte.
Hai importato una funzione senza scatenare l’esecuzione «da programma».
Cosa succede senza la guardia (controesempio)
⚠️ Attenzione — Side effect all’importazione
Codice operativo fuori da funzioni/classi, senza guardia, parte subito al primoimport.
Immagina svuota_cestino.py così:
def pulisci_directory():
print("Svuotamento dei file temporanei in corso...")
# Logica di eliminazione file
# Codice eseguito direttamente (errore di design)
pulisci_directory()
Se un giorno in statistiche.py scrivi import svuota_cestino solo per riusare una funzione secondaria, lo svuotamento parte all’istante. Per questo le azioni operative stanno sotto if __name__ == "__main__":.
Il pattern consigliato: main() e la guardia
Negli script di ai riparo (es. il generatore di password da terminale) trovi quasi sempre questo schema: logica in funzioni, ingresso in main(), guardia in fondo.
def calcola_valore(x):
return x * 2
def main():
risultato = calcola_valore(5)
print(f"Il risultato è {risultato}")
if __name__ == "__main__":
main()
Due vantaggi pratici:
- Ordine mentale — funzioni in alto, flusso principale in
main()in fondo. - Riutilizzo — chi importa può chiamare
tuo_file.main()senza riscrivere il flusso.
💡 Consiglio pratico — Cartella e
.venv
Per organizzare cartella, script e ambiente isolato fin dall’inizio: Struttura minima di un progetto Python «ai riparo».
Errori comuni da evitare
- Sbagliare gli underscore. La variabile è
__name__(due prima, due dopo). Il valore da confrontare è"__main__". Con_name_o underscore sbagliati rischiNameErroro una guardia che non scatta mai. - Confondere con C o Java. Lì
mainè spesso obbligatoria. In Pythonmain()è solo una convenzione: puoi chiamarlaesegui()oavvia(). Conta la rigaif __name__ == "__main__":. - File in cartelle diverse nel Lab B.
import salutacerca il modulo nel path; tieni i due file nella stessa cartella o gestisci il path correttamente. - Terminale nella cartella sbagliata. Prima
cdnella cartella del progetto, poipython/python3.
Domande Frequenti (FAQ)
Cosa significa if __name__ == "__main__" in Python?
È una condizione che è vera se lo script è stato lanciato direttamente dall’utente, e falsa se il file è stato solo importato come modulo.
Qual è la differenza pratica tra eseguire uno script e importarlo?
Eseguire (python script.py) avvia il programma. Importare (import script) carica funzioni/classi in memoria per riusarle altrove, senza far partire di default il flusso «da programma» — se hai messo la guardia.
Serve sempre questa riga in ogni file Python?
Non è obbligo di sintassi, ma è una raccomandazione forte. Se il file è solo una libreria di funzioni, puoi farne a meno. Se il file fa qualcosa (scrive file, chiama API, cancella dati), la guardia evita danni in caso di import accidentale.
Posso mettere il codice sotto la guardia senza definire main()?
Sì: cicli e print rientrati direttamente sotto l’if. Raggrupparli in def main(): resta più leggibile e riusabile.
Funziona uguale su Windows, macOS e Linux?
Sì: è una regola del linguaggio. Cambia solo come richiami l’interprete (python su Windows, spesso python3 su macOS/Linux).
Perché nell’output del Lab B vedo ancora le stampe 1 e 2 di saluta.py?
Perché all’import Python esegue il corpo del modulo. Le print fuori dalla guardia partono comunque; solo il blocco sotto if __name__ == "__main__": viene saltato.
Per i comandi di cartella e lancio script: Terminale: comandi minimi.
Per vedere il pattern in uno strumento reale: Generatore di password sicure da terminale.