Altro
Cosa fa se __name__ == "__main__":?
Che cosa fa il if __name__ == "__main__":
?
# Threading example
import time, thread
def myfunction(string, sleeptime, lock, *args):
while True:
lock.acquire()
time.sleep(sleeptime)
lock.release()
time.sleep(sleeptime)
if __name__ == "__main__":
lock = thread.allocate_lock()
thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock))
5496
3
Ogni volta che l'interprete Python legge un file sorgente, fa due cose:
__name__
, e poiVediamo come funziona e come si collega alla vostra domanda sui controlli di
__name__
che vediamo sempre negli script Python. Esempio di codiceUsiamo un esempio di codice leggermente diverso per esplorare come funzionano le importazioni e gli script. Supponiamo che quanto segue sia in un file chiamato
foo.py
.Variabili speciali
Quando l'interprete Python legge un file sorgente, prima definisce alcune variabili speciali. In questo caso, ci interessa la variabile
__name__
. Quando il vostro modulo è il programma principale Se state eseguendo il vostro modulo (il file sorgente) come programma principale, ad esempiol'interprete assegnerà la stringa
"__main__"
alla variabile__name__
, cioèQuando il tuo modulo è importato da un altro D'altra parte, supponiamo che qualche altro modulo sia il programma principale e importi il vostro modulo. Questo significa che c'è una dichiarazione come questa nel programma principale, o in qualche altro modulo che il programma principale importa:
In questo caso, l'interprete guarderà il nome del tuo modulo,
foo.py
, toglierà il.py
, e assegnerà quella stringa alla variabile__name__
del tuo modulo, cioèEseguire il codice del modulo
Dopo che le variabili speciali sono state impostate, l'interprete esegue tutto il codice del modulo, un'istruzione alla volta. Potreste voler aprire un'altra finestra sul lato con l'esempio di codice in modo da poter seguire questa spiegazione. Sempre
"before import"
(senza virgolette).math
e lo assegna ad una variabile chiamatamath
. Questo equivale a sostituireimport math
con quanto segue (si noti che__import__
è una funzione di basso livello in Python che prende una stringa e innesca l'effettiva importazione):"prima della funzioneA"
.def
, creando un oggetto funzione, poi assegna tale oggetto funzione ad una variabile chiamatafunzioneA
."prima della funzioneB"
.def
, creando un altro oggetto funzione, poi assegnandolo ad una variabile chiamatafunzioneB
."before __name__ guard"
. Solo quando il vostro modulo è il programma principale__name__
è stato effettivamente impostato a"__main__"
e chiama le due funzioni, stampando le stringhe"Funzione A"
e"Funzione B 10.0"
. Solo quando il vostro modulo è importato da un altro__name__
sarà"foo"
, non"__main__"
, e salterà il corpo della dichiarazioneif
. Sempre"dopo __name__ guard"
in entrambe le situazioni. Sommario In sintesi, ecco cosa verrebbe stampato nei due casi:Perché funziona così?
Potreste naturalmente chiedervi perché qualcuno dovrebbe volere questo. Beh, a volte si vuole scrivere un file
.py
che può essere sia usato da altri programmi e/o moduli come un modulo, e può anche essere eseguito come programma principale stesso. Esempi:Il vostro modulo è una libreria, ma volete avere una modalità script in cui eseguire alcuni test unitari o una demo.
Il tuo modulo è usato solo come programma principale, ma ha alcuni test unitari, e il framework di test funziona importando file
.py
come il tuo script ed eseguendo speciali funzioni di test. Non volete che provi ad eseguire lo script solo perché sta importando il modulo.Il tuo modulo è usato principalmente come programma principale, ma fornisce anche un'API di facile programmazione per gli utenti avanzati. Al di là di questi esempi, è elegante che eseguire uno script in Python è solo impostare alcune variabili magiche e importare lo script. L'esecuzione dello script è un effetto collaterale dell'importazione del modulo dello script. Cibo per la mente
Domanda: Posso avere più blocchi di controllo
__name__
? Risposta: è strano farlo, ma il linguaggio non te lo impedisce.Supponiamo che il seguente sia in
foo2.py
. Cosa succede se ditepython foo2.py
sulla linea di comando? Perché?-- lingua: python -->
__name__
infoo3.py
:}}Lingua: python -->
Quando il tuo script viene eseguito passandolo come comando all'interprete Python,
tutto il codice che è al livello di indentazione 0 viene eseguito. Le funzioni e le classi che sono definite sono, beh, definite, ma nessuno del loro codice viene eseguito. A differenza di altri linguaggi, non c'è una funzione
main()
che viene eseguita automaticamente - la funzionemain()
è implicitamente tutto il codice al livello superiore.In questo caso, il codice di primo livello è un blocco
if
.__name__
è una variabile incorporata che valuta il nome del modulo corrente. Tuttavia, se un modulo viene eseguito direttamente (come inmyscript.py
sopra), allora__name__
è invece impostato alla stringa"__main__"
. Quindi, puoi testare se il tuo script viene eseguito direttamente o se viene importato da qualcos'altro testandoSe il vostro script viene importato in un altro modulo, le sue varie definizioni di funzioni e classi verranno importate e il suo codice di primo livello verrà eseguito, ma il codice nel corpo della clausola
if
di cui sopra non verrà eseguito poiché la condizione non è soddisfatta. Come esempio di base, considerate i seguenti due script:;
Ora, se invocate l'interprete come
L'output sarà
Se invece si esegue
two.py
:Si ottiene
Così, quando il modulo
one
viene caricato, il suo__name__
è uguale a"one"
invece di"__main__"
.Se name == "main"
è la parte che viene eseguita quando lo script viene eseguito da (diciamo) la linea di comando usando un comando come
python myscript.py`.