28 Domanda: Cosa succede se __name__ == "__main__": fare?

domanda creata a Fri, May 25, 2018 12:00 AM

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))
    
5111
28 risposte                              28                         

Ogni volta che l'interprete Python legge un file sorgente, fa due cose:

  • imposta alcune variabili speciali come __name__ e poi

  • esegue tutto il codice trovato nel file.

Vediamo come funziona e come si riferisce alla tua domanda sui controlli __name__ che vediamo sempre negli script Python.

Esempio di codice

Usiamo un esempio di codice leggermente diverso per esplorare il funzionamento delle importazioni e degli script. Supponiamo che quanto segue sia in un file chiamato foo.py.

 
# Suppose this is foo.py.

print("before import")
import math

print("before functionA")
def functionA():
    print("Function A")

print("before functionB")
def functionB():
    print("Function B {}".format(math.sqrt(100)))

print("before __name__ guard")
if __name__ == '__main__':
    functionA()
    functionB()
print("after __name__ guard")

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 tuo modulo è il programma principale

Se stai eseguendo il tuo modulo (il file sorgente) come programma principale, ad es.

 
python foo.py

l'interprete assegnerà la stringa codificata "__main__" alla variabile __name__, cioè

 
# It's as if the interpreter inserts this at the top
# of your module when run as the main program.
__name__ = "__main__" 

Quando il tuo modulo è importato da un altro

D'altra parte, supponiamo che qualche altro modulo sia il programma principale e importi il ​​tuo modulo. Questo significa che c'è una dichiarazione come questa nel programma principale, o in qualche altro modulo che importa il programma principale:

 
# Suppose this is in some other main program.
import foo

In questo caso, l'interprete esaminerà il nome file del modulo, foo.py, rimuoverà il .py e assegnerà quella stringa alla variabile __name__ del modulo, cioè

 
# It's as if the interpreter inserts this at the top
# of your module when it's imported from another module.
__name__ = "foo"

Esecuzione del codice del modulo

Dopo aver impostato le variabili speciali, l'interprete esegue tutto il codice nel modulo, una dichiarazione alla volta. Potresti voler aprire un'altra finestra sul lato con il codice di esempio in modo da poter seguire questa spiegazione.

sempre

  1. Stampa la stringa "before import" (senza virgolette).

  2. Carica il modulo math e lo assegna a una variabile chiamata math. Ciò equivale a sostituire import math con il seguente (nota che __import__ è una funzione di basso livello in Python che accetta una stringa e attiva l'importazione effettiva):

 
# Find and load a module given its string name, "math",
# then assign it to a local variable called math.
math = __import__("math")
  1. Stampa la stringa "before functionA".

  2. Esegue il blocco def, creando un oggetto funzione, quindi assegnando quell'oggetto funzione a una variabile chiamata functionA.

  3. Stampa la stringa "before functionB".

  4. Esegue il secondo blocco def, creando un altro oggetto funzione, quindi assegnandolo a una variabile chiamata functionB.

  5. Stampa la stringa "before __name__ guard".

Solo quando il tuo modulo è il programma principale

  1. Se il tuo modulo è il programma principale, allora vedrà che __name__ è stato effettivamente impostato su "__main__" e chiama le due funzioni, stampando le stringhe "Function A" e "Function B 10.0".

Solo quando il tuo modulo è importato da un altro

  1. ( invece ) Se il tuo modulo non è il programma principale ma è stato importato da un altro, allora __name__ sarà "foo", non "__main__", e salterà il corpo dell'istruzione if.

sempre

  1. Stampa la stringa "after __name__ guard" in entrambe le situazioni.

Sommario

In breve, ecco cosa verrà stampato nei due casi:

 
# What gets printed if foo is the main program
before import
before functionA
before functionB
before __name__ guard
Function A
Function B 10.0
after __name__ guard
 
# What gets printed if foo is imported as a regular module
before import
before functionA
before functionB
before __name__ guard
after __name__ guard

Perché funziona così?

Potresti naturalmente chiedermi perché qualcuno lo vorrebbe. Bene, a volte si desidera scrivere un file .py che può essere utilizzato da altri programmi e /o moduli come modulo e può anche essere eseguito come il programma principale stesso. Esempi:

  • Il tuo modulo è una libreria, ma vuoi avere una modalità di script in cui vengono eseguiti alcuni test unitari o demo.

  • Il tuo modulo è usato solo come programma principale, ma ha alcuni test unitari e il framework di testing funziona importando .py file come il tuo script ed eseguendo speciali funzioni di test. Non vuoi che provi a eseguire lo script solo perché sta importando il modulo.

  • Il tuo modulo è usato principalmente come programma principale, ma fornisce anche un'API adatta ai programmatori per utenti esperti.

Al di là di questi esempi, è elegante che l'esecuzione di uno script in Python sia appena impostataalcune variabili magiche e importazione dello script. "Eseguire" lo script è un effetto collaterale dell'importazione del modulo dello script.

Cibo per il pensiero

  • Domanda: posso avere più blocchi di controllo __name__? Risposta: è strano farlo, ma la lingua non ti fermerà.

  • Supponiamo che quanto segue sia in foo2.py. Cosa succede se dici python foo2.py sulla riga di comando? Perché?

 
# Suppose this is foo2.py.

def functionA():
    print("a1")
    from foo2 import functionB
    print("a2")
    functionB()
    print("a3")

def functionB():
    print("b")

print("t1")
if __name__ == "__main__":
    print("m1")
    functionA()
    print("m2")
print("t2")
  • Ora, capisci cosa succederà se rimuovi il controllo __name__ in foo3.py:
 
# Suppose this is foo3.py.

def functionA():
    print("a1")
    from foo3 import functionB
    print("a2")
    functionB()
    print("a3")

def functionB():
    print("b")

print("t1")
print("m1")
functionA()
print("m2")
print("t2")
  • Che cosa farà quando viene usato come script? Quando viene importato come modulo?
 
# Suppose this is in foo4.py
__name__ = "__main__"

def bar():
    print("bar")

print("before __name__ guard")
if __name__ == "__main__":
    bar()
print("after __name__ guard")
    
5471
2019-06-24 03: 21: 09Z
  1. Per curiosità: cosa succede se eseguo subprocess.run('foo_bar.py') in uno script python? Suppongo che foo_bar verrà avviato con __name__ = '__main__' proprio come quando ho tipizzato foo_bar.py in cmd manualmente. È questo il caso? Prendendo in considerazione la risposta di @MrFooz, non ci dovrebbero essere problemi a fare questo e avere tanti moduli "principali" alla volta come mi pare. Anche la modifica del valore __name__ o la creazione indipendente di istanze (o istanze che si creano reciprocamente da subprocess) interagiscono tra loro dovrebbero essere normali come per Python. Mi manca qualcosa?
    2019-02-18 16: 09: 14Z
  2. @ hajef Hai ragione su come funzionano le cose con subprocess.run. Detto questo, un modo generalmente migliore di condividere il codice tra gli script è creare moduli e fare in modo che gli script chiamino i moduli condivisi anziché invocarsi l'un l'altro come script. È difficile eseguire il debug delle chiamate subprocess.run poiché la maggior parte dei debugger non supera i limiti del processo, può aggiungere un overhead del sistema non banale per creare e distruggere i processi aggiuntivi, ecc.
    2019-02-19 16: 16: 03Z
  3. ho un dubbio nell'esempio foo2.py nella sezione food for thought. Cosa succede da foo2.py import functionB do? A mio avviso importa solo foo2.py dalla funzione B
    2019-02-24 13: 47: 03Z
  4. @ MrFooz Non ho mai avuto intenzione di fare qualcosa di simile xD Mi è appena venuto in mente e ho capito che era abbastanza strano da poter aiutare ppl. avvolgendo le loro menti attorno a questo genere di cose. @ user471651 Perché il from foo2 import functionB deve importare foo2 dalla funzioneB? Questa è una contorsione semantica. from module import method importa il metodo dal modulo.
    2019-02-25 15: 51: 16Z
  5. sei un dio di Python? bella spiegazione: D
    2019-06-18 03: 20: 56Z

Quando lo script viene eseguito passandolo come comando all'interprete Python,

 
python myscript.py

viene eseguito tutto il codice che si trova al livello di indentazione 0. Le funzioni e le classi che sono definite sono, beh, definite, ma nessuno dei loro codici viene eseguito. A differenza di altri linguaggi, non esiste una funzione main() che viene eseguita automaticamente - la funzione main() è implicitamente tutto il codice al livello più alto.

In questo caso, il codice di livello superiore è un blocco if. __name__ è una variabile integrata che valuta il nome del modulo corrente. Tuttavia, se un modulo viene eseguito direttamente (come in myscript.py sopra), __name__ viene invece impostato sulla stringa "__main__". Pertanto, puoi verificare se il tuo script viene eseguito direttamente o importato da qualcos'altro testando

 
if __name__ == "__main__":
    ...

Se il tuo script viene importato in un altro modulo, le sue varie funzioni e definizioni di classe verranno importate e il codice di livello superiore verrà eseguito, ma il codice nel corpo della clausola if sopra non verrà eseguito poiché la condizione non è soddisfatta. Come esempio di base, prendi in considerazione i seguenti due script:

 
# file one.py
def func():
    print("func() in one.py")

print("top-level in one.py")

if __name__ == "__main__":
    print("one.py is being run directly")
else:
    print("one.py is being imported into another module")
 
# file two.py
import one

print("top-level in two.py")
one.func()

if __name__ == "__main__":
    print("two.py is being run directly")
else:
    print("two.py is being imported into another module")

Ora, se invochi l'interprete come

 
python one.py

L'output sarà

 
top-level in one.py
one.py is being run directly

Se invece esegui two.py:

 
python two.py

Ottieni

 
top-level in one.py
one.py is being imported into another module
top-level in two.py
func() in one.py
two.py is being run directly

Quindi, quando viene caricato il modulo one, il suo __name__ equivale a "one" invece di "__main__".

    
1640
2018-01-31 13: 28: 16Z

La spiegazione più semplice per la variabile __name__ (imho) è la seguente:

Crea i seguenti file.

 
# a.py
import b

e

 
# b.py
print "Hello World from %s!" % __name__

if __name__ == '__main__':
    print "Hello World again from %s!" % __name__

Eseguirli ti fornirà questo risultato:

 
$ python a.py
Hello World from b!

Come puoi vedere, quando un modulo viene importato, Python imposta globals()['__name__'] in questo modulo sul nome del modulo. Inoltre, al momento dell'importazione, viene eseguito tutto il codice nel modulo. Poiché l'istruzione if restituisce False questa parte non viene eseguita.

 
$ python b.py
Hello World from __main__!
Hello World again from __main__!

Come puoi vedere, quando viene eseguito un file, Python imposta globals()['__name__'] in questo file su "__main__". Questa volta, l'istruzione if restituisce True ed è in esecuzione.

    
653
2018-12-18 09: 25: 19Z
  

Che cosa fa il if __name__ == "__main__":?

Per delineare le nozioni di base:

  • La variabile globale, __name__, nel modulo che è il punto di accesso al tuo programma, è '__main__'. Altrimenti, è il nome con il quale importi il ​​modulo.

  • Quindi, il codice sotto il blocco if verrà eseguito solo se il modulo è il punto di ingresso al tuo programma.

  • Consente al codice nel modulo di essere importabile da altri moduli, senza eseguire il blocco di codice sottostante all'importazione.


Perché ne abbiamo bisogno?

Sviluppo e test del codice

Dì che stai scrivendo uno script Python progettato per essere usato come modulo:

 
def do_important():
    """This function does something very important"""

potresti testare il modulo aggiungendo questa chiamata della funzione in basso:

 
do_important()

e eseguirlo (al prompt dei comandi) con qualcosa di simile:

 
~$ python important.py

Il problema

Tuttavia, se vuoi importare il modulo in un altro script:

 
import important

Durante l'importazione, la funzione do_important verrebbe chiamata, quindi probabilmente commenteresti la tua chiamata di funzione, do_important(), nella parte inferiore.

 
# do_important() # I must remember to uncomment to execute this!

E poi dovrai ricordare se hai o meno commentato la chiamata della funzione di test. E questa complessità in più significherebbe che probabilmente ti dimenticherai, rendendo più problematico il tuo processo di sviluppo.

Un modo migliore

La variabile __name__ punta allo spazio dei nomi ovunque si trovi l'interprete Python al momento.

All'interno di un modulo importato, è il nome di quel modulo.

Ma all'interno del modulo primario (o in una sessione interattiva di Python, ovvero nell'interprete Read, Eval, Print Loop o REPL) si sta eseguendo tutto dal suo "__main__".

Quindi, se controlli prima di eseguire:

 
if __name__ == "__main__":
    do_important()

Con quanto sopra, il tuo codice verrà eseguito solo quando lo stai eseguendo come modulo principale (o intenzionalmente lo chiamerai da un altro script).

An Even Better Way

C'è un modo Python per migliorare su questo, però.

Che cosa succede se vogliamo eseguire questo processo aziendale dall'esterno del modulo?

Se inseriamo il codice che vogliamo esercitare mentre sviluppiamo e testiamo in una funzione come questa, quindi eseguiamo il controllo per '__main__' subito dopo:

 
def main():
    """business logic for when running this module as the primary one!"""
    setup()
    foo = do_important()
    bar = do_even_more_important(foo)
    for baz in bar:
        do_super_important(baz)
    teardown()

# Here's our payoff idiom!
if __name__ == '__main__':
    main()

Ora abbiamo una funzione finale per la fine del nostro modulo che verrà eseguita se eseguiamo il modulo come modulo primario.

Ciò consentirà il modulo e le sue funzioni e classi da importata in altri script senza eseguire la funzione main, e consentirà anche il modulo (e le sue funzioni e classi) da detta durante l'esecuzione di un diverso modulo '__main__', vale a dire

 
import important
important.main()

Questo idioma si possono trovare anche nella documentazione Python in una spiegazione del modulo __main__. questo testo afferma:

  

Questo modulo rappresenta lo scopo (altrimenti anonimo) in cui il   il programma principale dell'interprete viene eseguito - comandi letti da   input standard, da un file di script o da un prompt interattivo. esso   è questo ambiente in cui la stanza "script condizionale" idiomatica   fa girare uno script:

 
if __name__ == '__main__':
    main()
    
470
2018-03-27 02: 27: 47Z

if __name__ == "__main__" è la parte che viene eseguita quando lo script viene eseguito da (ad esempio) la riga di comando utilizzando un comando come python myscript.py.

    
110
2015-07-10 15: 49: 13Z
  

Che cosa fa if __name__ == "__main__":?

__name__ è una variabile globale (in Python, global significa in realtà sul livello di modulo ) esistente in tutti gli spazi dei nomi. In genere è il nome del modulo (come un tipo str).

Come unico caso speciale, comunque, in qualunque processo Python tu corra, come in mycode.py:

 
python mycode.py

al namespace globale altrimenti anonimo viene assegnato il valore di '__main__' al suo __name__.

Pertanto, tra cui le linee finali

 
if __name__ == '__main__':
    main()
  • alla fine del tuo script mycode.py,
  • quando è il modulo principale, entry-point che viene eseguito da un processo Python,

causerà l'esecuzione della funzione main definita in modo univoco.

Un altro vantaggio dell'uso di questo costrutto: puoi anche importare il tuo codice come modulo in un altro script e quindi eseguire la funzione principale se e quando il tuo programma decide:

 
import mycode
# ... any amount of other code
mycode.main()
    
71
2017-01-10 17: 35: 04Z

Ci sono molti aspetti diversi qui sulla meccanica del codice in questione, il "come", ma per me niente di tutto ciò ha senso finché non ho capito il "perché". Questo dovrebbe essere particolarmente utile per i nuovi programmatori.

prendi il file "ab.py":

 
def a():
    print('A function in ab file');
a()

E un secondo file "xy.py":

 
import ab
def main():
    print('main function: this is where the action is')
def x():
    print ('peripheral task: might be useful in other projects')
x()
if __name__ == "__main__":
    main()
  

Che cosa sta facendo questo codice?

Quando si esegue xy.py, si import ab. L'istruzione import esegue immediatamente il modulo durante l'importazione, quindi le operazioni di ab vengono eseguite prima del resto di xy. Una volta finito con ab, continua con xy.

L'interprete tiene traccia di quali script sono in esecuzione con __name__. Quando esegui uno script, indipendentemente da come lo hai chiamato, l'interprete lo chiama "__main__", rendendolo lo script master o "home" a cui viene restituito dopo aver eseguito uno script esterno.

Qualsiasi altro script chiamato da questo script "__main__" viene assegnato il suo nome file come __name__ (ad es. __name__ == "ab.py"). Quindi, la linea if __name__ == "__main__": è il test dell'interprete per determinare se sta interpretando /analizzando lo script 'home' che è stato inizialmente eseguito, o se sta sbirciando temporaneamente in un altro script (esterno). Ciò offre al programmatore la flessibilità di avere lo script in modo diverso se viene eseguito direttamente o chiamato esternamente.

Passiamo attraverso il codice sopra riportato per capire cosa sta succedendo, concentrandoci prima sulle linee non indirizzate e sull'ordine in cui appaiono negli script. Ricorda che la funzione - o def - i blocchi non fanno nulla da soli finché non vengono chiamati. Ciò che l'interprete potrebbe dire se borbottava a se stesso:

  • Apri xy.py come file "casa"; chiamalo "__main__" nella variabile __name__.
  • Importa e apri il file con il __name__ == "ab.py".
  • Oh, una funzione. Lo ricorderò.
  • Ok, funzione a(); L'ho appena saputo. Stampa di ' Una funzione in un file ab '.
  • Fine del file; torna a "__main__"!
  • Oh, una funzione. Lo ricorderò.
  • Un altro.
  • Funzione x(); ok, stampa ' attività periferica: potrebbe essere utile in altri progetti '.
  • Cos'è questo? Una dichiarazione if. Bene, la condizione è stata soddisfatta (la variabile __name__ è stata impostata su "__main__"), quindi inserirò la funzione main() e stamperò la funzione principale : è qui che l'azione è .

Le due righe in basso significano: "Se questo è lo script "__main__" o 'home', eseguire la funzione main()". Ecco perché vedrai un blocco def main(): in alto, che contiene il flusso principale delle funzionalità dello script.

  

Perché implementarlo?

Ricordi cosa ho detto prima riguardo alle dichiarazioni di importazione? Quando si importa un modulo, non lo "riconosce" solo e attende ulteriori istruzioni - in realtà esegue tutte le operazioni eseguibili contenute nello script. Quindi, mettere la carne del tuo script nella funzione main() lo mette in quarantena in modo efficace, mettendolo in isolamento in modo che non venga immediatamente eseguito quando importato da un altro script.

Ancora una volta, ci saranno delle eccezioni, ma la pratica comune è che il main() non viene solitamente chiamato esternamente. Quindi potresti essere vintodering ancora una cosa: se non chiamiamo main(), perché chiamiamo il copione? È perché molte persone strutturano i loro script con funzioni autonome costruite per essere eseguite indipendentemente dal resto del codice nel file. Successivamente verranno chiamati da qualche altra parte nel corpo della sceneggiatura. Il che mi porta a questo:

  

Ma il codice funziona senza di esso

Sì, è vero. Queste funzioni separate possono essere chiamate da uno script in linea che non è contenuto in una funzione main(). Se siete abituati (come lo sono io, nelle prime fasi di apprendimento della programmazione) a creare script in linea che fanno esattamente ciò che vi serve, e cercherete di capirlo di nuovo se avete ancora bisogno di quell'operazione di nuovo. beh, non sei abituato a questo tipo di struttura interna del tuo codice, perché è più complicato da compilare e non è così intuitivo da leggere.

Ma quello è uno script che probabilmente non può avere le sue funzioni chiamate esternamente, perché se lo facesse inizierebbe immediatamente a calcolare e assegnare variabili. Ed è probabile che se stai cercando di riutilizzare una funzione, il tuo nuovo script è strettamente correlato a quello vecchio che ci saranno variabili in conflitto.

Nel dividere le funzioni indipendenti, ottieni la possibilità di riutilizzare il tuo lavoro precedente chiamandoli in un altro script. Ad esempio, "example.py" potrebbe importare "xy.py" e chiamare x(), facendo uso della funzione 'x' da "xy.py". (Forse sta capitalizzando la terza parola di una determinata stringa di testo, creando una matrice NumPy da una lista di numeri e squadrandoli, o detragliando una superficie 3D.Le possibilità sono infinite.)

(Per inciso, questa domanda contiene una risposta di @kindall che finalmente mi ha aiutato a capire - il perché, non il come. Purtroppo è stato contrassegnato come un duplicato di questo , che ritengo sia un errore.)

    
62
2018-05-23 22: 29: 32Z

Quando ci sono determinate affermazioni nel nostro modulo (M.py) che vogliamo essere eseguite quando verrà eseguito come principale (non importato), possiamo mettere quelle dichiarazioni (test-case, dichiarazioni di stampa) sotto questo blocco if.

Come impostazione predefinita (quando il modulo viene eseguito come principale, non importato) la variabile __name__ è impostata su "__main__" e quando verrà importata la variabile __name__ avrà un valore diverso, molto probabilmente il nome del modulo ('M') . Ciò è utile nell'esecuzione di diverse varianti di un modulo insieme e nella separazione del loro specifico input & istruzioni di output e anche se ci sono casi di test.

In breve , usa questo blocco 'if __name__ == "main"' per impedire che il codice (certo) venga eseguito quando il modulo viene importato.

    
45
2018-05-23 22: 07: 29Z

Diamo un'occhiata alla risposta in un modo più astratto:

Supponiamo di avere questo codice in x.py:

 
...
<Block A>
if __name__ == '__main__':
    <Block B>
...

I blocchi A e B vengono eseguiti quando stiamo eseguendo "x.py".

Ma il blocco A (e non B) viene eseguito quando eseguiamo un altro modulo, "y.py" per esempio, in cui xy è importato e il codice viene eseguito da lì (come quando una funzione in "x. py "è chiamato da y.py).

    
35
2015-03-04 20: 31: 20Z

In parole semplici, __name__ è una variabile definita per ogni script che definisce se lo script viene eseguito come modulo principale o viene eseguito come un modulo importato.

Quindi se abbiamo due script;

 
#script1.py
print "Script 1's name: {}".format(__name__)

e

 
#script2.py
import script1
print "Script 2's name: {}".format(__name__)

L'output dell'esecuzione di script1 è

 
Script 1's name: __main__

E l'output dell'esecuzione di script2 è:

 
Script1's name is script1
Script 2's name: __main__

Come puoi vedere, __name__ ci dice quale codice è il modulo 'principale'. Questo è grandioso, perché puoi semplicemente scrivere codice e non preoccuparti di problemi strutturali come in C /C ++, dove, se un file non implementa una funzione 'principale', allora non può essere compilato come un eseguibile e se lo fa, iot non può quindi essere usato come libreria.

Supponiamo di scrivere uno script Python che faccia qualcosa di eccezionale e di implementare un carico di funzioni utili per altri scopi. Se voglio usarli posso semplicemente importare il tuo script e usarli senza eseguire il tuo programma (dato che il tuo codice viene eseguito solo all'interno del contesto if __name__ == "__main__":). Mentre in C /C ++ dovresti dividere quei pezzi in un modulo separato che poi include il file. Immagina la situazione di seguito;

 Importazione complicata in C

Le frecce sono collegamenti di importazione. Per tre moduli ciascuno che tenta di includere il codice dei moduli precedenti, ci sono sei file (nove, contando i file di implementazione) e cinque collegamenti. Ciò rende difficile includere altro codice in un progetto C a meno che non sia compilato specificamente come una libreria. Ora immaginalo per Python:

 Elegante importazione in Python

Scrivi un modulo e se qualcuno vuole usare il tuo codice lo importerà e la variabile __name__ può aiutare a separare la parte eseguibile del programma dalla parte della libreria.

    
35
2018-05-23 22: 28: 19Z
  1. L'illustrazione di C /C ++ è errata: 3 volte lo stesso nome di unità ( file1 ).
    2018-01-11 12: 59: 53Z

Quando esegui Python in modo interattivo, alla variabile locale __name__ viene assegnato un valore di __main__. Allo stesso modo, quando si esegue un modulo Python dalla riga di comando, anziché importarlo in un altro modulo, al suo attributo __name__ viene assegnato un valore di __main__, anziché il nome effettivo del modulo. In questo modo, i moduli possono esaminare il proprio valore __name__ per determinare da soli il modo in cui vengono utilizzati, sia come supporto per un altro programma o come applicazione principale eseguita dalla riga di comando. Quindi, il seguente idioma è abbastanza comune nei moduli Python:

 
if __name__ == '__main__':
    # Do something appropriate here, like calling a
    # main() function defined elsewhere in this module.
    main()
else:
    # Do nothing. This module has been imported by another
    # module that wants to make use of the functions,
    # classes and other useful bits it has defined.
    
32
2013-12-11 11: 23: 53Z

Si consideri:

 
if __name__ == "__main__":
    main()

Controlla se l'attributo __name__ dello script Python è "__main__". In altre parole, se il programma stesso viene eseguito, l'attributo sarà __main__, quindi il programma verrà eseguito (in questo caso la funzione main()).

Tuttavia, se lo script Python viene utilizzato da un modulo, verrà eseguito qualsiasi codice all'esterno dell'istruzione if, quindi if \__name__ == "\__main__" viene utilizzato solo per verificare se il programma viene utilizzato come modulo o meno, e quindi decide se eseguire il codice.

    
29
2018-05-23 22: 31: 42Z

Prima di spiegare qualcosa su if __name__ == '__main__' è importante capire cos'è __name__ e cosa fa.

  

Che cos'è __name__?

__name__ è un DunderAlias ​​ - può essere pensato come una variabile globale (accessibile dai moduli) e funziona in modo simile a global .

È una stringa (globale come menzionato sopra) come indicato da type(__name__) (che produce <class 'str'>) ed è uno standard integrato per entrambi Python 3 e Python 2 versioni.

  

Dove:

Non può essere utilizzato solo negli script, ma può anche essere trovato sia nell'interprete che nei moduli /pacchetti.

Interprete:

 
>>> print(__name__)
__main__
>>>

Script:

test_file.py :

 
print(__name__)

Risultato in __main__

Modulo o pacchetto:

somefile.py:

 
def somefunction():
    print(__name__)

test_file.py:

 
import somefile
somefile.somefunction()

Risultato in somefile

Si noti che quando viene utilizzato in un pacchetto o modulo, __name__ prende il nome del file. Il percorso del modulo attuale o del percorso del pacchetto non è dato, ma ha il suo DunderAlias ​​__file__, che lo consente.

Dovresti vedere che, dove __name__, dove è il file principale (o programma) restituirà sempre __main__, e se è un modulo /pacchetto, o qualcosa che sta scappando da qualche altro Lo script Python restituirà il nome del file da cui ha avuto origine.

  

Practice:

Essere una variabile significa che il suo valore può essere sovrascritto ("can" non significa "should"), sovrascrivendo il valore di __name__ si tradurrà in una mancanza di leggibilità. Quindi non farlo, per nessuna ragione. Se hai bisogno di una variabile, definisci una nuova variabile.

Si presume sempre che il valore di __name__ sia __main__ o il nome del file. Ancora una volta la modifica di questo valore predefinito causerà più confusione sul fatto che andrà bene, causando problemi in futuro.

Esempio:

 
>>> __name__ = 'Horrify' # Change default from __main__
>>> if __name__ == 'Horrify': print(__name__)
...
>>> else: print('Not Horrify')
...
Horrify
>>>

In generale, è considerata buona pratica includere il if __name__ == '__main__' negli script.

  

Adesso rispondi a if __name__ == '__main__':

Ora sappiamo che il comportamento delle cose __name__ diventa più chiaro:

Un if è un'istruzione di controllo del flusso che contiene il blocco di codice verrà eseguito se il valore indicato è vero. Abbiamo visto che __name__ può prendere entrambi  __main__ o il nome del file da cui è stato importato.

Ciò significa che se __name__ è uguale a __main__ allora il file deve essere il file principale e deve essere effettivamente in esecuzione (o è l'interprete), non un modulo o pacchetto importato nello script.

Se effettivamente __name__ assume il valore di __main__, verrà eseguito qualsiasi elemento del blocco di codice.

Questo ci dice che se il file in esecuzione è il file principale (o stai eseguendo direttamente dall'interprete), allora questa condizione deve essere eseguita. Se è un pacchetto, non dovrebbe farlo e il valore non sarà __main__.

  

Moduli:

__name__ può essere utilizzato anche nei moduli per definire il nome di un modulo

  

Varianti:

È anche possibile fare altre cose, meno comuni ma utili con __name__, alcune delle quali mostrerò qui:

Esecuzione solo se il file è un modulo o pacchetto:

 
if __name__ != '__main__':
    # Do some useful things 

Esecuzione di una condizione se il file è il principale e un altro se non lo è:

 
if __name__ == '__main__':
    # Execute something
else:
    # Do some useful things

Puoi anche usarlo per fornire funzioni /utility di aiuto eseguibili su pacchetti e moduli senza l'uso elaborato di librerie.

Consente inoltre di eseguire i moduli dalla riga di comando come script principali, che può essere anche molto utile.

    
25
2018-05-23 22: 39: 09Z

Penso che sia meglio interrompere la risposta in modo approfondito e con parole semplici:

__name__: Ogni modulo in Python ha un attributo speciale chiamato __name__. È una variabile built-in che restituisce il nome del modulo.

__main__: Come altri linguaggi di programmazione, anche Python ha un punto di ingresso per l'esecuzione, cioè principale. '__main__' è il nome dell'ambito in cui viene eseguito il codice di livello superiore . Fondamentalmente hai due modi per usare un modulo Python: eseguilo direttamente come script o importalo. Quando un modulo viene eseguito come script, il suo __name__ è impostato su __main__.

Pertanto, il valore dell'attributo __name__ è impostato su __main__ quando il modulo viene eseguito come programma principale. Altrimenti il ​​valore di __name__ è impostato per contenere il nome del modulo.

    
22
2018-05-23 22: 30: 36Z

È speciale quando viene chiamato un file Python dalla riga di comando. Questo viene in genere utilizzato per chiamare una funzione "main ()" o eseguire un altro codice di avvio appropriato, come ad esempio la gestione degli argomenti della riga di comando.

Potrebbe essere scritto in diversi modi. Un altro è:

 
def some_function_for_instance_main():
    dosomething()


__name__ == '__main__' and some_function_for_instance_main()

Non sto dicendo che dovrestiQuesto è nel codice di produzione, ma serve a illustrare che non c'è nulla di "magico" su if __name__ == '__main__'. È una buona convenzione per invocare una funzione principale nei file Python.

    
20
2018-09-03 07: 05: 11Z
  1. Considererei questa cattiva forma come lo sei 1) basandomi sugli effetti collaterali e 2) abusando del and. and viene utilizzato per verificare se due istruzioni booleane sono entrambe vere. Poiché non sei interessato al risultato del and, una dichiarazione if comunica più chiaramente le tue intenzioni.
    2013-12-26 18: 07: 26Z
  2. Lasciando da parte la questione se lo sfruttamento del comportamento di cortocircuito degli operatori booleani come un meccanismo di controllo del flusso sia cattivo stile o no, il problema più grande è che questo non risponde affatto alla domanda .
    2015-07-10 15: 33: 06Z

Ci sono un certo numero di variabili che il sistema (interprete Python) fornisce per i file sorgente (moduli). Puoi ottenere i loro valori ogni volta che vuoi, quindi concentriamoci sulla __ nome __ variabile /attributo:

Quando Python carica un file di codice sorgente, esegue tutto il codice trovato in esso. (Si noti che non chiama tutti i metodi e le funzioni definiti nel file, ma li definisce.)

Prima che l'interprete esegua il file del codice sorgente, definisce alcune variabili speciali per quel file; __ name __ è una di quelle variabili speciali che Python definisce automaticamente per ogni file di codice sorgente.

Se Python sta caricando questo file del codice sorgente come programma principale (cioè il file che si esegue), allora imposta la variabile __ nome __ speciale per questo file per avere un valore "__ main__" .

Se viene importato da un altro modulo, __ nome __ verrà impostato sul nome di quel modulo.

Quindi, nel tuo esempio in parte:

 
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))

significa che il blocco di codice:

 
lock = thread.allocate_lock()
thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock))

verrà eseguito solo quando si esegue direttamente il modulo; il blocco di codice non verrà eseguito se un altro modulo sta chiamando /importandolo perché il valore di __ nome __ non sarà uguale a " principale " in quella particolare istanza.

Spero che questo aiuti.

    
19
2016-07-20 09: 30: 24Z

if __name__ == "__main__": è fondamentalmente l'ambiente di script di livello superiore e specifica all'interprete che ('Ho la priorità più alta da eseguire prima').

'__main__' è il nome dell'ambito in cui viene eseguito il codice di livello superiore. Il __name__ di un modulo è impostato su '__main__' quando viene letto dallo standard input, uno script o da un prompt interattivo.

 
if __name__ == "__main__":
    # Execute only if run as a script
    main()
    
16
2018-05-23 22: 14: 07Z

Il motivo per

 
if __name__ == "__main__":
    main()

serve principalmente a evitare il blocco dell'importazione problemi che potrebbero sorgere da con codice importato direttamente . Si desidera eseguire main() se il file è stato richiamato direttamente (vale a dire il caso __name__ == "__main__"), ma se il codice è stato importato, l'importatore deve inserire il codice dal modulo principale vero per evitare problemi di blocco dell'importazione.

Un effetto collaterale è che accedi automaticamente a una metodologia che supporta più punti di accesso. È possibile eseguire il programma utilizzando main() come punto di ingresso, ma non è necessario . Mentre setup.py prevede main(), altri strumenti utilizzano punti di ingresso alternativi. Ad esempio, per eseguire il file come processo gunicorn, si definisce una funzione app() anziché main(). Proprio come con setup.py, gunicorn importa il tuo codice in modo che tu non voglia che faccia qualcosa mentre viene importato (a causa dellaproblema di blocco della porta).

    
14
2018-04-18 21: 05: 59Z
  1. Buono a sapere su blocco dell'importazione . Potresti spiegare per accedere a una metodologia che [...] parte un po 'di più?
    2018-01-11 13: 06: 38Z
  2. @ Wolf: sicuro. Ho aggiunto alcune frasi sulla metodologia dei punti di ingresso multipli.
    2018-04-14 00: 26: 20Z

Ho letto molto durante le risposte su questa pagina. Direi che se conosci la cosa, di sicuro capirai quelle risposte, altrimenti sarai ancora confuso.

Per essere brevi, devi conoscere diversi punti:

  1. L'azione import a esegue in realtà tutto ciò che può essere eseguito in "a"

  2. A causa del punto 1, potresti non voler che tutto venga eseguito in "a" durante l'importazione

  3. Per risolvere il problema di cui al punto 2, python consente di inserire un controllo di condizione

  4. __name__ è una variabile implicita in tutti i moduli .py; quando a.py viene importato, il valore di __name__ del modulo a.py viene impostato sul nome del file "a"; quando a.py viene eseguito direttamente usando "python a.py", che significa a.py è il punto di ingresso, quindi il valore di __name__ del modulo a.py è impostato su una stringa __main__

  5. In base al meccanismo su come python imposta la variabile __name__ per ciascun modulo, sai come raggiungere il punto 3? La risposta è abbastanza facile, giusto? Metti una condizione se: if __name__ == "__main__": ...; puoi anche mettere se __name__ == "a" a seconda delle tue esigenze funzionali

La cosa importante a cui Python è speciale è il punto 4! Il resto è solo logica di base.

    
13
2018-06-24 15: 48: 36Z
  1. Sì, il punto 1 è fondamentale per capire. Da ciò, la necessità di questo meccanismo diventa chiara.
    2019-03-24 21: 16: 18Z

Si consideri:

 
print __name__

L'output di cui sopra è __main__.

 
if __name__ == "__main__":
  print "direct method"

L'affermazione sopra è vera e stampa "metodo diretto" . Supponiamo che importando questa classe in un'altra classe non stampi "metodo diretto" perché, durante l'importazione, imposterà __name__ equal to "first model name".

    
13
2019-02-06 23: 16: 06Z
  

Puoi rendere il file utilizzabile come script e come modulo importable .

fibo.py (un modulo chiamato fibo)

 
# Other modules can IMPORT this MODULE to use the function fib
def fib(n):    # write Fibonacci series up to n
    a, b = 0, 1
    while b < n:
        print(b, end=' ')
        a, b = b, a+b
    print()

# This allows the file to be used as a SCRIPT
if __name__ == "__main__":
    import sys
    fib(int(sys.argv[1]))

Riferimento: https://docs.python.org/3.5/tutorial/modules. html

    
12
2017-03-13 21: 44: 26Z

Questa risposta è per i programmatori Java che stanno imparando Python. Ogni file Java contiene in genere una classe pubblica. Puoi usare quella classe in due modi:

  1. Chiama la classe da altri file. Devi solo importarlo nel programma chiamante.

  2. Esegui la classe stand alone, a scopo di test.

Per quest'ultimo caso, la classe dovrebbe contenere un metodo public static void main (). In Python questo scopo è servito dall'etichetta '__main__' definita globalmente.

    
8
2018-10-18 03: 09: 32Z

Se questo file .py viene importato da altri file .py, il codice sotto "l'istruzione if" non verrà eseguito.

Se questo .py viene eseguito da python this_py.py sotto shell, o doppio clic su Windows. il codice sotto "l'istruzione if" sarà eseguito.

Di solito è scritto per i test.

    
5
2018-06-19 11: 44: 29Z

Crea un file, a.py :

 
print(__name__) # It will print out __main__

__name__ è sempre uguale a __main__ ogni volta che quel file è eseguito direttamente che mostra che questo è il file principale.

Crea un altro file, b.py , nella stessa directory:

 
import a  # Prints a

Eseguilo. Stampa a , ovvero il nome del file che è importato .

Quindi, per mostrare due diversi comportamenti dello stesso file , questo è un trucco comunemente usato:

 
# Code to be run when imported into another python file

if __name__ == '__main__':
    # Code to be run only when run directly
    
4
2018-05-23 22: 34: 14Z

se nome == ' principale ':

Vediamo se __name__ == '__main__': abbastanza spesso.

Controlla se un modulo viene importato o meno.

In altre parole, il codice all'interno del blocco if verrà eseguito solo quando il codice viene eseguito direttamente. Qui directly significa not imported.

Vediamo cosa fa usando un semplice codice che stampa il nome del modulo:

 
# test.py
def test():
   print('test module name=%s' %(__name__))

if __name__ == '__main__':
   print('call test()')
   test()

Se eseguiamo il codice direttamente tramite python test.py, il nome del modulo è __main__:

 
call test()
test module name=__main__
    
3
2018-05-23 22: 36: 51Z

Tutte le risposte hanno praticamente spiegato la funzionalità. Ma fornirò un esempio del suo utilizzo che potrebbe aiutare a chiarire ulteriormente il concetto.

Supponi di avere due file Python, a.py e b.py. Ora, a.py importa b.py. Eseguiamo il file a.py, dove il codice "import b.py" viene eseguito per primo. Prima dell'esecuzione del resto del codice a.py, il codice nel file b.py deve essere eseguito completamente.

Nel codice b.py c'è un codice che è esclusivo di quel file b.py e non vogliamo nessun altro file (diverso dal file b.py), che ha importato il file b.py, in eseguilo.

Ecco cosa controlla questa riga di codice. Se è il file principale (cioè, b.py) che esegue il codice, che in questo caso non è (a.py è il file principale in esecuzione), quindi viene eseguito solo il codice.

    
3
2018-05-23 22: 38: 56Z

Semplicemente è il punto di ingresso per eseguire il file come la funzione main nel linguaggio di programmazione C .

    
2
2019-02-06 23: 13: 57Z
  1. Questa risposta presuppone che l'OP (o qualsiasi utente con una domanda simile) abbia familiarità con C e sa cos'è un punto di ingresso.
    2019-02-22 12: 44: 37Z
  2. Questa risposta presuppone anche che nessun codice (a parte le definizioni senza effetti collaterali) avvenga prima del blocco if __name__ == "__main__". Tecnicamente la parte superiore dello script eseguito è il punto di ingresso del programma.
    2019-04-09 21: 35: 39Z

Ogni modulo in python ha un attributo che viene chiamato come nome . Il valore dell'attributo nome è" main " quando il modulo viene eseguito direttamente. Altrimenti il ​​valore di nome è il nome del modulo.

Piccolo esempio da spiegare in breve.

 
#Script test.py

apple = 42

def hello_world():
    print("I am inside hello_world")

if __name__ == "__main__":
    print("Value of __name__ is: ", __name__)
    print("Going to call hello_world")
    hello_world()

Possiamo eseguirlo direttamente come

 
python test.py  

Output

 
Value of __name__ is: __main__
Going to call hello_world
I am inside hello_world

Ora supponiamo di chiamare lo script sopra da altri script

 
#script external_calling.py

import test
print(test.apple)
test.hello_world()

print(test.__name__)

Quando lo esegui

 
python external_calling.py

Output

 
42
I am inside hello_world
test

Quindi, sopra è autoesplicativo che quando chiami test da un altro script, se loop name in test.py non verrà eseguito.

    
1
2019-06-12 09: 28: 39Z
fonte posta Qui