Cosa succede se __name__ == “__main__”: fare?


6067

Dato il seguente codice, cosa fa 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))

Le if __name__ == "__main__":condizioni di blocco sono state deprecate / obsolete per quanto riguarda Python 3? Ho trovato alcune informazioni che lo affermano.
carloswm85,

2
@ carloswm85 Non è vero.
Giorgos Myrianthous

Risposte:


6648

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

  • imposta alcune variabili speciali come __name__, e quindi

  • esegue tutto il codice trovato nel file.

Vediamo come funziona e come si collega alla tua domanda sui __name__controlli che vediamo sempre negli script Python.

Esempio di codice

Usiamo 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.

# 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'interpeter Python legge un file sorgente, per prima cosa definisce alcune variabili speciali. In questo caso, ci preoccupiamo per la __name__variabile.

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 __name__variabile, ovvero

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

Quando il modulo è importato da un altro

D'altra parte, supponiamo che qualche altro modulo sia il programma principale e importa il tuo modulo. Ciò significa che nel programma principale è presente un'affermazione come questa o in alcuni altri moduli il programma principale importa:

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

L'interprete cercherà il tuo foo.pyfile (insieme alla ricerca di alcune altre varianti) e prima di eseguire quel modulo, assegnerà il nome "foo"dall'istruzione import alla __name__variabile, ovvero

# 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, un'istruzione alla volta. Potresti voler aprire un'altra finestra sul lato con l'esempio di codice in modo da poter seguire insieme a questa spiegazione.

Sempre

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

  2. Carica il mathmodulo e lo assegna a una variabile chiamata math. Ciò equivale alla sostituzione import mathcon quanto segue (si noti 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 defblocco, creando un oggetto funzione, quindi assegnando quell'oggetto funzione a una variabile chiamata functionA.

  3. Stampa la stringa "before functionB".

  4. Esegue il secondo defblocco, 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, vedrà che __name__era 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__lo sarà "foo", no "__main__", e salterà il corpo ifdell'istruzione.

Sempre

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

Sommario

In sintesi, ecco cosa sarebbe 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 in questo modo?

Potresti naturalmente chiederti perché qualcuno vorrebbe questo. Bene, a volte vuoi scrivere un .pyfile che può essere sia usato da altri programmi e / o moduli come modulo, sia come programma principale stesso. Esempi:

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

  • Il modulo viene utilizzato solo come programma principale, ma ha alcuni test unitari e il framework di test funziona importando .pyfile come lo script ed eseguendo speciali funzioni di test. Non vuoi che provi a eseguire lo script solo perché sta importando il modulo.

  • Il modulo viene utilizzato principalmente come programma principale, ma fornisce anche un'API intuitiva per programmatori per utenti esperti.

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

Cibo per la mente

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

  • Supponiamo che sia presente quanto segue foo2.py. Cosa succede se dici python foo2.pysulla 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, scopri cosa accadrà se rimuovi il __name__check-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")
  • Cosa farà questo se usato come script? Se 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")

14
Per curiosità: cosa succede se corro subprocess.run('foo_bar.py')in uno script Python? Suppongo che foo_barsarà iniziato __name__ = '__main__'proprio come quando scrivo foo_bar.pymanualmente cmd. È così? Tenendo conto della risposta di @MrFooz non dovrebbe esserci alcun problema nel fare questo e avere tutti i moduli "principali" alla volta che mi piace. Anche cambiare il __name__valore o avere diverse istanze create in modo indipendente (o istanze che si sono create reciprocamente subprocess) interagire tra loro dovrebbe essere un affare come al solito per Python. Mi manca qualcosa?
Hajef,

12
@hajef Hai ragione su come funzionano le cose subprocess.run. Detto questo, un modo generalmente migliore di condividere il codice tra script è creare moduli e fare in modo che gli script chiamino i moduli condivisi invece di invocarsi a vicenda come script. È difficile eseguire il debug delle subprocess.runchiamate poiché la maggior parte dei debugger non supera i limiti del processo, può aggiungere un sovraccarico di sistema non banale per creare e distruggere i processi aggiuntivi, ecc.
Mr Fooz,

4
ho un dubbio nell'esempio di foo2.py nella sezione "Food for Thought". Cosa fa la funzione di importazione foo2.pyB? Dal mio punto di vista importa solo foo2.py da functionB
user471651

1
@MrFooz Non ho mai avuto intenzione di fare nulla del genere xD Mi è appena venuto in mente e mi sono reso conto che era abbastanza strano da poter aiutare il ppl. avvolgendo le loro menti attorno a questo genere di cose. @ user471651 Perché from foo2 import functionBimportare foo2 da functionB? Questa è una contorsione semantica. from module import methodimporta il metodo dal modulo.
Hajef,

2
Uno dei moduli che possono importare il codice è multiprocessing, in particolare, rendendo questo test necessario su Windows.
Yann Vernier,

1801

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

python myscript.py

tutto il codice che si trova al livello di rientro 0 viene eseguito. Le funzioni e le classi definite sono ben definite, ma nessuno del loro codice viene eseguito. A differenza di altre lingue, non esiste alcuna main()funzione che viene eseguita automaticamente: la main()funzione è implicitamente tutto il codice al livello superiore.

In questo caso, il codice di livello superiore è un ifblocco. __name__è una variabile integrata che valuta il nome del modulo corrente. Tuttavia, se un modulo viene eseguito direttamente (come myscript.pysopra), __name__viene invece impostato sulla stringa "__main__". Pertanto, è possibile verificare se lo script viene eseguito direttamente o importato da qualcos'altro mediante test

if __name__ == "__main__":
    ...

Se lo script viene importato in un altro modulo, verranno importate le sue varie definizioni di funzioni e classi e verrà eseguito il suo codice di livello superiore, ma il codice nell'allora corpo della ifclausola sopra non verrà eseguito poiché la condizione è non soddisfatti. Come esempio di base, considerare 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 two.pyinvece corri :

python two.py

Hai capito

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

Pertanto, quando il modulo oneviene caricato, è __name__uguale "one"invece di "__main__".


Ottima risposta, questa è stata la risposta più chiara secondo me. +1!
TheTechRobo36414519

+1 per quel modo di pensarci: la prima riga rientrata viene eseguita solo all'inizio, fino a quando non esegui le funzioni su quella prima riga
Elijah Mock

719

La spiegazione più semplice per la __name__variabile (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__

Eseguendoli otterrai questo output:

$ python a.py
Hello World from b!

Come puoi vedere, quando un modulo viene importato, Python imposta globals()['__name__']in questo modulo il nome del modulo. Inoltre, al momento dell'importazione viene eseguito tutto il codice nel modulo. Poiché l' ifistruzione valuta Falsequesta 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 "__main__". Questa volta, l' ifistruzione valuta Truee viene eseguita.


513

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

Per delineare le basi:

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

  • Pertanto, il codice sotto il ifblocco verrà eseguito solo se il modulo è il punto di ingresso al programma.

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


perché ne abbiamo bisogno?

Sviluppo e test del codice

Supponi di scrivere uno script Python progettato per essere utilizzato come modulo:

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

È possibile testare il modulo aggiungendo questa chiamata della funzione in basso:

do_important()

ed eseguendolo (al prompt dei comandi) con qualcosa del tipo:

~$ python important.py

Il problema

Tuttavia, se si desidera importare il modulo in un altro script:

import important

All'importazione, la do_importantfunzione verrebbe chiamata, quindi probabilmente commenterai la tua chiamata di funzione do_important(), in fondo.

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

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

Un modo migliore

La __name__variabile punta allo spazio dei nomi in qualsiasi momento si trovi l'interprete Python.

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

Ma all'interno del modulo primario (o di una sessione interattiva di Python, ovvero Leggi, Eval, Print Loop o REPL dell'interprete) stai 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 esegui come modulo primario (o lo chiami intenzionalmente da un altro script).

Un modo ancora migliore

C'è un modo Pythonic per migliorare questo, però.

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

Se inseriamo il codice che vogliamo esercitare mentre sviluppiamo e testiamo una funzione come questa e facciamo il nostro controllo '__main__'immediatamente 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.

Consentirà al modulo e alle sue funzioni e classi di essere importati in altri script senza eseguire la mainfunzione e consentirà inoltre di chiamare il modulo (e le sue funzioni e classi) quando viene eseguito da un '__main__'modulo diverso , ad es.

import important
important.main()

Questo idioma può essere trovato anche nella documentazione di Python in una spiegazione del __main__modulo. Quel testo afferma:

Questo modulo rappresenta l'ambito (altrimenti anonimo) in cui viene eseguito il programma principale dell'interprete: comandi letti dall'input standard, da un file di script o da un prompt interattivo. È questo ambiente in cui la strana idiomatica "script condizionale" provoca l'esecuzione di uno script:

if __name__ == '__main__':
    main()

125

if __name__ == "__main__"è la parte che viene eseguita quando lo script viene eseguito (diciamo) dalla riga di comando usando un comando simile python myscript.py.


2
Perché un file helloworld.pycon solo print("hello world")al suo interno può essere eseguito con comando python helloworld.pyanche quando non c'è if __name__ == "__main__"?
hi15,

83

Cosa fa if __name__ == "__main__":?

__name__è una variabile globale (in Python, globale significa effettivamente a livello di modulo ) che esiste in tutti gli spazi dei nomi. In genere è il nome del modulo (come strtipo).

Come unico caso speciale, tuttavia, in qualunque processo Python tu esegua, come in mycode.py:

python mycode.py

allo spazio dei nomi globale altrimenti anonimo viene assegnato il valore di '__main__'al suo __name__.

Quindi, comprese le linee finali

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

farà mainfunzionare la funzione definita in modo univoco del tuo script .

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

import mycode
# ... any amount of other code
mycode.main()

72

Ci sono molte diverse interpretazioni qui sulla meccanica del codice in questione, il "Come", ma per me nulla di tutto ciò ha avuto senso fino a quando ho capito il "Perché". Ciò 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()

Cosa sta facendo questo codice?

Quando esegui xy.py, tu import ab. La dichiarazione import esegue immediatamente il modulo al momento dell'importazione, quindi able operazioni vengono eseguite prima del resto di xy's. Una volta terminato ab, continua con xy.

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

A qualsiasi altro script richiamato da questo "__main__"script viene assegnato il 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 temporaneamente sbirciando in un altro script (esterno). Ciò offre al programmatore la flessibilità necessaria affinché lo script si comporti in modo diverso se viene eseguito direttamente o chiamato esternamente.

Esaminiamo il codice sopra per capire cosa sta succedendo, concentrandoci prima sulle linee non indentate 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. Cosa potrebbe dire l'interprete se borbottava da solo:

  • Apri xy.py come file 'home'; chiamalo "__main__"nella __name__variabile.
  • Importa e apri il file con il __name__ == "ab.py".
  • Oh, una funzione. Me lo ricorderò.
  • Ok, funzione a(); L'ho appena imparato. Stampa " Una funzione nel file ab ".
  • Fine del file; torna a "__main__"!
  • Oh, una funzione. Me lo ricorderò.
  • Un altro.
  • Funzione x(); ok, stampa " compito periferico: potrebbe essere utile in altri progetti ".
  • Che cos'è questo? Una ifdichiarazione. Bene, la condizione è stata soddisfatta (la variabile __name__è stata impostata su "__main__"), quindi inserirò la main()funzione e stampa ' funzione principale: questo è dove si trova l'azione '.

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

Perché implementarlo?

Ricordi cosa ho detto in precedenza sulle dichiarazioni di importazione? Quando si importa un modulo, non solo lo "riconosce" e si attendono ulteriori istruzioni, ma in realtà vengono eseguite tutte le operazioni eseguibili contenute nello script. Quindi, mettendo la carne del tuo script nella main()funzione, la metti in quarantena efficacemente, mettendola in isolamento in modo che non venga eseguita immediatamente quando viene importata da un altro script.

Ancora una volta, ci saranno eccezioni, ma la pratica comune è che di main()solito non viene chiamata esternamente. Quindi potresti chiederti un'altra cosa: se non stiamo chiamando main(), perché stiamo chiamando la sceneggiatura? È perché molte persone strutturano i loro script con funzioni autonome create per essere eseguite indipendentemente dal resto del codice nel file. Successivamente vengono chiamati da qualche altra parte nel corpo della sceneggiatura. Il che mi porta a questo:

Ma il codice funziona senza di esso

Sì, è giusto. Queste funzioni separate possono essere richiamate da uno script in linea non contenuto in una main()funzione. Se sei abituato (come lo sono io, nelle mie prime fasi di apprendimento della programmazione) a costruire script in linea che facciano esattamente ciò di cui hai bisogno, e proverai a capirlo di nuovo se mai hai bisogno di ripetere l'operazione. Beh, non sei abituato a questo tipo di struttura interna al tuo codice, perché è più complicato da costruire e non è così intuitivo da leggere.

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

Dividendo le funzioni indipendenti, ottieni la possibilità di riutilizzare il tuo lavoro precedente chiamandoli in un altro script. Ad esempio, "esempio.py" potrebbe importare "xy.py" e chiamare x(), usando la funzione 'x' da "xy.py". (Forse sta capitalizzando la terza parola di una determinata stringa di testo; creando un array NumPy da un elenco di numeri e quadrandoli; o togliendo una superficie 3D. Le possibilità sono illimitate.)

(A parte questo , questa domanda contiene una risposta di @kindall che alla fine mi ha aiutato a capire - il perché, non il come. Purtroppo è stato contrassegnato come duplicato di questo , che penso sia un errore.)


52

Quando ci sono alcune istruzioni nel nostro modulo ( M.py) che vogliamo essere eseguite quando sarà in esecuzione come principale (non importato), possiamo mettere quelle istruzioni (casi di prova, istruzioni di stampa) sotto questo ifblocco.

Come impostazione predefinita (quando il modulo funziona come principale, non importato) la __name__variabile è impostata su "__main__", e quando verrà importata la __name__variabile otterrà un valore diverso, molto probabilmente il nome del modulo ( 'M'). Questo è utile per eseguire insieme diverse varianti di un modulo e separare le loro specifiche istruzioni di input e output e anche se ci sono casi di test.

In breve , utilizzare questo ' if __name__ == "main"' blocco per impedire l'esecuzione (certo) di codice durante l'importazione del modulo.


43

In parole povere, __name__è una variabile definita per ogni script che definisce se lo script viene eseguito come modulo principale o se viene eseguito come 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 è fantastico, perché puoi semplicemente scrivere codice e non devi preoccuparti di problemi strutturali come in C / C ++, dove, se un file non implementa una funzione "principale", non può essere compilato come eseguibile e, se lo fa, non può quindi essere utilizzato come libreria.

Supponi di scrivere uno script Python che fa 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 nel if __name__ == "__main__":contesto). Considerando che in C / C ++ dovresti suddividere questi pezzi in un modulo separato che include quindi il file. Immagina la situazione qui sotto;

Importazione complicata in C

Le frecce sono collegamenti di importazione. Per tre moduli ognuno dei quali cerca 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 libreria. Ora immaginalo per Python:

Importazione elegante in Python

Scrivi un modulo e se qualcuno vuole usare il tuo codice, lo importa e la __name__variabile può aiutare a separare la parte eseguibile del programma dalla parte della libreria.


2
L'illustrazione C / C ++ è errata: 3 volte lo stesso nome di unità ( file1 ).
Lupo,

40

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 siamo in esecuzione x.py.

Ma solo il blocco A (e non B) viene eseguito quando stiamo eseguendo un altro modulo, y.pyad esempio, in cui x.pyviene importato e il codice viene eseguito da lì (come quando x.pyviene chiamata una funzione in y.py).


1
Non sono stato in grado di modificare il post (minimo 6 caratteri se è richiesta la modifica). La riga 14 ha "xy" anziché "x.py".
alwaysLearning

35

Quando si esegue Python in modo interattivo, alla __name__variabile locale 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 __name__attributo viene assegnato un valore __main__anziché il nome effettivo del modulo. In questo modo, i moduli possono esaminare il proprio __name__valore per determinare autonomamente come vengono utilizzati, sia come supporto per un altro programma sia come applicazione principale eseguita dalla riga di comando. Pertanto, il seguente linguaggio è 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.

34

Prendere in considerazione:

if __name__ == "__main__":
    main()

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

Tuttavia, se lo script Python viene utilizzato da un modulo, ifverrà eseguito qualsiasi codice esterno all'istruzione, 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.


sembra che sia passato troppo tempo a scrivere la risposta luminosa +1
snr

27

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

Che cosa è __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__)(cedimento <class 'str'>), ed è uno standard integrato per entrambe le versioni Python 3 e Python 2 .

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

Con il risultato di __main__

Modulo o pacchetto:

somefile.py:

def somefunction():
    print(__name__)

test_file.py:

import somefile
somefile.somefunction()

Con il risultato di somefile

Si noti che quando utilizzato in un pacchetto o modulo, __name__prende il nome del file. Il percorso del modulo attuale o del percorso del pacchetto non è indicato, ma ha i propri DunderAlias __file__, che lo consentono.

Si dovrebbe notare che, dove __name__, dove è il file principale (o programma) sarà sempre tornare __main__, e se si tratta di un modulo / package, o tutto ciò che è in esecuzione fuori qualche altro script Python, restituirà il nome del file in cui si è originario di.

Pratica:

Essere una variabile significa che il suo valore può essere sovrascritto ("can" non significa "dovrebbe"), la sovrascrittura del valore __name__comporterà una mancanza di leggibilità. Quindi non farlo, per qualsiasi motivo. Se hai bisogno di una variabile, definisci una nuova variabile.

Si presume sempre che il valore di __name__essere __main__o il nome del file. Ancora una volta, la modifica di questo valore predefinito causerà maggiore confusione sul fatto che farà del bene, causando ulteriori problemi in futuro.

esempio:

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

È considerata buona pratica in generale includere gli if __name__ == '__main__'script in.

Ora per rispondere if __name__ == '__main__':

Ora sappiamo che il comportamento delle __name__cose diventa più chiaro:

An ifè un'istruzione di controllo del flusso che contiene il blocco di codice verrà eseguito se il valore fornito è vero. Abbiamo visto che __name__può assumere uno __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__prende il valore di __main__allora, tutto ciò che è in quel blocco di codice verrà eseguito.

Questo ci dice che se il file in esecuzione è il file principale (o se si esegue direttamente dall'interprete), tale condizione deve essere eseguita. Se è un pacchetto, non dovrebbe esserlo e il valore non lo sarà __main__.

moduli:

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

varianti:

È anche possibile fare altre cose meno comuni ma utili __name__, alcune che 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 è quello principale e un'altra in caso contrario:

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

È inoltre possibile utilizzarlo per fornire funzioni / utilità di guida eseguibili su pacchetti e moduli senza l'uso elaborato delle librerie.

Inoltre, consente di eseguire i moduli dalla riga di comando come script principali, che possono anche essere molto utili.


25

Penso che sia meglio rompere la risposta in profondità e in parole semplici:

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

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

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


23

È speciale per quando un file Python viene chiamato dalla riga di comando. In genere viene utilizzato per chiamare una funzione "main ()" o eseguire altri codici di avvio appropriati, 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 dovresti usarlo nel codice di produzione, ma serve a illustrare che non c'è nulla di "magico" if __name__ == '__main__'. È una buona convenzione per invocare una funzione principale nei file Python.


7
Considererei questa cattiva forma dato che 1) fai affidamento su effetti collaterali e 2) abusi and. andviene utilizzato per verificare se due istruzioni booleane sono entrambe vere. Dal momento che non sei interessato al risultato di and, una ifdichiarazione comunica più chiaramente le tue intenzioni.
jpmc26,

8
Lasciando da parte la questione se lo sfruttamento del comportamento di cortocircuito degli operatori booleani come meccanismo di controllo del flusso sia un cattivo stile o meno, il problema più grande è che questo non risponde affatto alla domanda .
Mark Amery,

@MarkAmery haha, sheesh, ora lo fa. 😊
contratto del Prof. Falken è stato violato il

19

Esistono numerose variabili che il sistema (interprete Python) fornisce per i file sorgente (moduli). Puoi ottenere i loro valori ogni volta che vuoi, quindi concentriamoci sulla variabile / attributo __name__ :

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

Prima che l'interprete esegua il file di 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 di codice sorgente come programma principale (ovvero il file che si esegue), imposta la variabile __name__ speciale per questo file per avere un valore "__main__" .

Se questo viene importato da un altro modulo, __name__ 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 lo chiama / importa perché il valore di __name__ non sarà uguale a " main " in quella particolare istanza.

Spero che questo aiuti.


17

if __name__ == "__main__": è fondamentalmente l'ambiente di script di livello superiore e specifica l'interprete che ('Ho la massima priorità da eseguire per primo').

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

if __name__ == "__main__":
    # Execute only if run as a script
    main()

17

Ho letto così tanto in tutte le risposte in questa pagina. Direi che, se conosci la cosa, sicuramente capirai quelle risposte, altrimenti rimarrai ancora confuso.

Per essere brevi, è necessario conoscere diversi punti:

  1. import a l'azione esegue effettivamente tutto ciò che può essere eseguito in "a"

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

  3. Per risolvere il problema al punto 2, python consente di effettuare un controllo delle condizioni

  4. __name__è una variabile implicita in tutti i .pymoduli; quando a.pyviene importato, il valore di __name__di a.pymodulo è impostato per il nome del file " a"; quando a.pyviene eseguito direttamente utilizzando " python a.py", il che significa che a.pyè il punto di ingresso, quindi il valore __name__di a.pymodule è impostato su una stringa__main__

  5. In base al meccanismo con cui Python imposta la variabile __name__per ciascun modulo, sai come raggiungere il punto 3? La risposta è abbastanza semplice, vero? Mettere un se la condizione: if __name__ == "__main__": ...; puoi anche mettere se a __name__ == "a"seconda delle tue esigenze funzionali

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


1
Sì, il punto 1 è fondamentale per capire. Da ciò, diventa evidente la necessità di questo meccanismo.
Eureka,

16

Prendere in considerazione:

print __name__

L'output per quanto sopra è __main__.

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

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


14

È possibile rendere il file utilizzabile sia come script che come modulo modificabile .

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


14

La ragione per

if __name__ == "__main__":
    main()

serve principalmente per evitare i problemi di blocco delle importazioni che potrebbero derivare dall'importazione diretta del codice . Si desidera main()eseguire se il file è stato richiamato direttamente (è il __name__ == "__main__"caso), ma se il codice è stato importato, l'importatore deve inserire il codice dal vero modulo principale per evitare problemi di blocco dell'importazione.

Un effetto collaterale è che accedi automaticamente a una metodologia che supporta più punti di ingresso. È possibile eseguire il programma utilizzando main()come punto di ingresso, ma non è necessario . Mentre setup.pyprevisto main(), altri strumenti utilizzano punti di ingresso alternativi. Ad esempio, per eseguire il file come gunicornprocesso, è necessario definire una app()funzione anziché un main(). Allo stesso modo setup.py, gunicornimporta il tuo codice in modo che tu non voglia che faccia nulla mentre viene importato (a causa del problema del blocco dell'importazione).


3
Buono a sapersi sul blocco delle importazioni . Potresti spiegare come accedere a una metodologia che [...] parte un po 'di più?
Lupo,

1
@Lupo: certo. Ho aggiunto alcune frasi sulla metodologia dei punti di ingresso multipli.
personal_cloud

11

Questa risposta è per i programmatori Java che imparano Python. Ogni file Java in genere contiene 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 da solo, a scopo di test.

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


11

Il codice sotto if __name__ == '__main__': verrà eseguito solo se il modulo viene invocato come script .

Ad esempio, considera il seguente modulo my_test_module.py:

# my_test_module.py

print('This is going to be printed out, no matter what')

if __name__ == '__main__':
    print('This is going to be printed out, only if user invokes the module as a script')

1a possibilità: importazione my_test_module.pyin un altro modulo

# main.py

import my_test_module

if __name__ == '__main__':
    print('Hello from main.py')

Ora se invochi main.py:

python main.py 

>> 'This is going to be printed out, no matter what'
>> 'Hello from main.py'

Si noti che viene eseguita solo l' print()istruzione di livello superiore in my_test_module.


2a possibilità: invoca my_test_module.pycome una sceneggiatura

Ora, se si esegue my_test_module.pycome uno script Python, print()verranno rispettate entrambe le istruzioni:

python my_test_module.py

>>> 'This is going to be printed out, no matter what'
>>> 'This is going to be printed out, only if user invokes the module as a script'

10

Ogni modulo in Python ha un attributo chiamato __name__. Il valore __name__ dell'attributo è __main__ quando il modulo viene eseguito direttamente, come python my_module.py. Altrimenti (come quando dici import my_module) il valore di __name__ è 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  

Produzione

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

Supponiamo ora di chiamare sopra lo script da altri script

#script external_calling.py

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

print(test.__name__)

Quando esegui questo

python external_calling.py

Produzione

42
I am inside hello_world
test

Quindi, sopra è autoesplicativo che quando si chiama test da un altro script, se il loop __name__in test.pynon verrà eseguito.


6

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

Se questo .py è gestito da python this_py.pysotto shell, o fatto doppio clic su Windows. il codice sotto "l'istruzione if" verrà eseguito.

Di solito è scritto per il test.


6

Se l'interprete python esegue un modulo particolare, __name__la variabile globale avrà valore"__main__"

  def a():
      print("a")
  def b():
      print("b")

  if __name__ == "__main__": 

          print ("you can see me" )
          a()
  else: 

          print ("You can't see me")
          b()

Quando esegui questo script, puoi vedermi

un'

Se importate questo file dite A nel file B ed eseguite il file B, quindi if __name__ == "__main__"nel file A diventa falso, quindi stampa Non potete vedermi

B


5

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

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

Nel codice b.py è presente un codice esclusivo di quel file b.py e non vogliamo altri file (tranne il file b.py), che ha importato il file b.py, per eseguirlo.

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


4

Crea un file, a.py :

print(__name__) # It will print out __main__

__name__è sempre uguale a __main__ogni volta che quel file viene eseguito direttamente mostrando che questo è il file principale.

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

import a  # Prints a

Eseguirlo. Stamperà a , cioè, il nome del file che viene 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

se name == ' main ':

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

Verifica se un modulo viene importato o meno.

In altre parole, il codice all'interno del ifblocco verrà eseguito solo quando il codice viene eseguito direttamente. Qui directlysignificanot 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__

4

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


8
Questa risposta presuppone che l'OP (o qualsiasi utente con una domanda simile) abbia familiarità con C e sappia cos'è un punto di ingresso.
Arredond

1
Questa risposta presuppone anche che nessun codice (diverso dalle definizioni senza effetti collaterali) avvenga prima del if __name__ == "__main__"blocco. Tecnicamente la parte superiore dello script eseguito è il punto di ingresso del programma.
Charlie Harding,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.