2013-04-01 13 views
5

quando ho eseguito:Python exec e __name__

exec "print __name__" 

la stampa __main__.

Ma quando ho eseguito:

exec "print __name__" in {} 

la stampa __builtin__.

Come eseguire il secondo esempio per stampare anche __main__?

Quello che cerco di ottenere è di eseguire un pezzo di codice con exec in modo che dal punto di vista di esso sembra essere stato eseguito dalla riga di comando.

Vorrei sintonizzare il codice con ambito pulito ma il secondo esempio interrompe il codice basandosi su if __name__ == "__main__". Come risolvere questo?

risposta

4

Si potrebbe utilizzare imp.load_module invece:

import imp 

with open(mainfile) as src: 
    imp.load_module('__main__', src, mainfile, (".py", "r", imp.PY_SOURCE)) 

Questo importa il file del modulo __main__, eseguirlo.

Nota che è necessario un oggetto file effettivo quando il tipo è impostato su imp.PY_SOURCE, quindi è necessario creare un file temporaneo affinché funzioni correttamente se il codice sorgente proviene da un luogo diverso da un file.

In caso contrario, si può sempre impostare manualmente __name__:

>>> src = '''\ 
... if __name__ == '__main__': print 'Main!' 
... else: print 'Damn', __name__ 
... ''' 
>>> exec src 
Main! 
>>> exec src in {} 
Damn __builtin__ 
>>> exec src in {'__name__':'__main__'} 
Main! 
+0

Purtroppo non riesco a creare un file temporaneo su disco. Non c'è un modo per eseguire una stringa semplice come se fosse eseguita dalla riga di comando? E un'altra domanda sulla tua risposta: sembra che stia importando (come in "import") il file - importa o esegue il file? C'è una differenza? –

+0

Per importare un modulo, * deve * essere eseguito. –

+0

Nota che l'aspettativa che '__name__ == '__main __'' funzioni implica che stai eseguendo i moduli qui. –

0

Una soluzione è quella di fornire il __name__ esplicito nel dict exec ution:

exec "print __name__" in {'__name__': '__main__'} 
+0

E 'sicuro? Voglio dire è l'unica differenza tra il codice dalla domanda e l'esecuzione del codice dalla riga di comando solo questa correzione? So che ci sono più chiavi come '__doc__' ma questa correzione è essenziale per far sembrare il codice dalla riga di comando? –

Problemi correlati