2013-04-01 10 views
5

Wenn ich laufen:Python exec und __name__

exec "print __name__" 

druckt __main__.

Aber wenn ich laufen:

exec "print __name__" in {} 

druckt __builtin__.

Wie das zweite Beispiel zu drucken __main__?

Was ich versuche zu erreichen, ist ein Stück Code mit exec zu laufen, so dass es aus der Perspektive der es aussieht wie es von der Befehlszeile ausgeführt wurde.

Ich möchte den Code mit sauberen Bereich tun, aber das zweite Beispiel bricht den Code unter if __name__ == "__main__". Wie behebe ich das?

Antwort

4

Sie imp.load_module statt:

import imp 

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

Dies importiert die Datei als __main__ Modul, es ausführt.

Beachten Sie, dass ein tatsächliches Dateiobjekt erforderlich ist, wenn der Typ auf imp.PY_SOURCE festgelegt ist. Daher müssen Sie eine temporäre Datei erstellen, damit der Quellcode von einer anderen Stelle als einer Datei kommt.

Andernfalls kann immer __name__ manuell einstellen:

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

Ich kann leider keine temporäre Datei auf der Festplatte erstellen. Gibt es keine Möglichkeit, eine einfache Zeichenfolge auszuführen, als ob sie von der Befehlszeile aus ausgeführt würde? Und noch eine Frage zu Ihrer Antwort: Es sieht so aus, als würde es die Datei importieren (wie in 'import') - importiert oder führt sie die Datei aus? Ist da ein Unterschied? –

+0

Um ein Modul zu importieren, muss * * ausgeführt werden. –

+0

Beachten Sie, dass die Erwartung, dass '__name__ ==' __main __ 'funktioniert, impliziert, dass Sie hier Module ausführen. –

0

Eine Lösung ist die __name__ ausdrücklich in Ihrem exec ution dict bieten:

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

Ist es sicher? Ich meine, ist der einzige Unterschied zwischen dem Code aus Frage und Ausführen des Codes von der Befehlszeile nur dieses Update? Ich weiß, dass es mehr Schlüssel wie '__doc__' gibt, aber ist dieser Fix wichtig, damit er wie Code von der Befehlszeile aussieht? –