Articolo originale: Python if __name__ == __main__ Explained with Code Examples di Goran Aviani

Tradotto e adattato da: Dario Di Cillo

Quando l'interprete legge un file Python, imposta alcune variabili speciali e poi esegue il codice dal file.

Una di queste variabili è chiamata __name__.

Seguendo quest'articolo passo passo e leggendo gli snippet di codice, imparerai come utilizzare if __name__ == "__main__" e perché è così importante.

I moduli Python

I file Python vengono chiamati moduli e sono identificati dall'estensione .py. Un modulo può definire funzioni, classi e variabili.

Quando l'interprete esegue un modulo, la variabile __name__ viene impostata come __main__ se il modulo in esecuzione è il programma principale.

Se invece il codice sta importando il modulo da un altro modulo, la variabile __name__ verrà impostata secondo il nome del modulo stesso.

Vediamo un esempio. Crea un modulo Python chiamato file_one.py e incolla questo blocco di codice al suo interno:

# Python file one module

print("File one __name__ is set to: {}" .format(__name__))
file_one.py

Eseguendo questo file vedrai esattamente ciò di cui stiamo parlando: la variabile __name__ viene impostata su __main__:

File one __name__ is set to: __main__

Adesso aggiungi un altro file chiamato file_two.py e incolla questo codice al suo interno:

# Python module to import

print("File two __name__ is set to: {}" .format(__name__))
file_two.py

Inoltre, modifica il codice nel file file_one.py in questo modo, così da importare il modulo file_two:

# Python module to execute
import file_two

print("File one __name__ is set to: {}" .format(__name__))
file_one.py

L'esecuzione del codice in file_one mostrerà ancora che la variabile __name__ nel file file_one non è cambiata ed è ancora impostata su __main__, ma ora la variabile __name__ in file_two viene impostata sul nome del modulo, ovvero file_two.

Il risultato dovrebbe essere questo:

File two __name__ is set to: file_two
File one __name__ is set to: __main__

Se invece esegui direttamente file_two vedrai che la variabile verrà impostata su __main__:

File two __name__ is set to: __main__

La variabile __name__ per il file/modulo che viene eseguito sarà sempre __main__ mentre per tutti gli altri moduli importati verrà impostata secondo il nome del modulo.

Convenzioni sulla denominazione dei file Python

Il modo usuale di utilizzare __name__ e __main__ è il seguente:

if __name__ == "__main__":
   Do something here

Vediamo come funziona con degli esempi pratici e come usare queste variabili.

Modifica file_one e file_two in questo modo:

file_one:

# Python module to execute
import file_two

print("File one __name__ is set to: {}" .format(__name__))

if __name__ == "__main__":
   print("File one executed when ran directly")
else:
   print("File one executed when imported")
`file_one.py`

file_two:

# Python module to import

print("File two __name__ is set to: {}" .format(__name__))

if __name__ == "__main__":
   print("File two executed when ran directly")
else:
   print("File two executed when imported")
file_two.py

Di nuovo, eseguendo file_one vedrai che il programma riconosce quale dei due moduli è __main__ eseguendo il codice in base alla nostra prima istruzione if else.

Ecco il risultato:

File two __name__ is set to: file_two
File two executed when imported
File one __name__ is set to: __main__
File one executed when ran directly

Adesso esegui file_two e vedrai che la variabile __name__ è impostata su __main__:

File two __name__ is set to: __main__
File two executed when ran directly

Quando moduli come questo vengono importati ed eseguiti, le loro funzioni saranno importate e il codice di primo livello verrà eseguito.

Per vedere questo processo in azione, modifica i tuoi file in questo modo:

file_one:

# Python module to execute
import file_two

print("File one __name__ is set to: {}" .format(__name__))

def function_one():
   print("Function one is executed")

def function_two():
   print("Function two is executed")

if __name__ == "__main__":
   print("File one executed when ran directly")
else:
   print("File one executed when imported")
file_one.py

file_two:

# Python module to import

print("File two __name__ is set to: {}" .format(__name__))

def function_three():
   print("Function three is executed")

if __name__ == "__main__":
   print("File two executed when ran directly")
else:
   print("File two executed when imported")

Ora le funzioni sono state caricate ma non vengono eseguite.

Per eseguire una di queste funzioni, modifica la parte `if __name__ == "__main__"` del file file_one come mostrato qui sotto:

if __name__ == "__main__":
   print("File one executed when ran directly")
   function_two()
else:
   print("File one executed when imported")

Eseguendo file_one dovresti vedere questo:

File two __name__ is set to: file_two
File two executed when imported
File one __name__ is set to: __main__
File one executed when ran directly
Function two is executed

Puoi eseguire funzioni anche da file importati. Per farlo, modifica la parte if __name__ == "__main__" di file_one in questo modo:

if __name__ == "__main__":
   print("File one executed when ran directly")
   function_two()
   file_two.function_three()
else:
   print("File one executed when imported")

Dovresti ottenere questo risultato:

File two __name__ is set to: file_two
File two executed when imported
File one __name__ is set to: __main__
File one executed when ran directly
Function two is executed
Function three is executed

Supponiamo che il modulo file_two sia molto grande con tante funzioni (nel nostro caso due) e che tu non desideri importarle tutte. Modifica file_two come mostrato di seguito:

# Python module to import

print("File two __name__ is set to: {}" .format(__name__))

def function_three():
   print("Function three is executed")

def function_four():
   print("Function four is executed")

if __name__ == "__main__":
   print("File two executed when ran directly")
else:
   print("File two executed when imported")
file_two.py

Per importare funzioni specifiche dal modulo, usa il blocco di import from nel file file_one:

# Python module to execute
from file_two import function_three

print("File one __name__ is set to: {}" .format(__name__))

def function_one():
   print("Function one is executed")

def function_two():
   print("Function two is executed")

if __name__ == "__main__":
   print("File one executed when ran directly")
   function_two()
   function_three()
else:
   print("File one executed when imported")
file_one.py

Conclusione

Un utilizzo molto utile della variabile __name__, può essere quello per cui desideri che un file venga eseguito come programma principale o importato da altri moduli. Possiamo usare un if __name__ == "__main__" per permettere o impedire che parti di codice vengano eseguite importando dei moduli.

Quando l'interprete di Python legge un file, la variabile __name__ viene impostata come __main__ se è il modulo in esecuzione, oppure secondo il nome del modulo se è stato importato. Leggendo il file, viene eseguito tutto il codice di primo livello ma non le funzioni e le classi (dato che saranno solamente importate).

Bra gjort! (Che vuol dire "Ben fatto!" in svedese)