2013-04-01 60 views
5

當我運行:Python的exec和__name__

exec "print __name__" 

它打印__main__

但是當我運行:

exec "print __name__" in {} 

它打印__builtin__

如何使第二個示例也打印__main__

我試圖實現的是使用exec運行一段代碼,以便從它的角度來看,它看起來像是從命令行運行。

我想用乾淨的範圍來代碼,但第二個例子打破了依賴if __name__ == "__main__"的代碼。如何解決這個問題?

回答

4

你可以使用imp.load_module代替:

import imp 

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

此文件導入爲__main__模塊,執行它。

請注意,當類型設置爲imp.PY_SOURCE時,它需要一個實際的文件對象,所以如果您的源代碼來自文件以外的其他位置,您需要創建一個臨時文件才能工作。

否則,可以隨時設置__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

我不能在磁盤上創建一個臨時文件。沒有辦法像執行命令行一樣執行純字符串嗎?還有一個關於你的回覆的問題:它看起來好像它正在導入(如在'import'中)該文件 - 導入還是執行該文件?有區別嗎? –

+0

爲了導入模塊,它*具有*被執行。 –

+0

請注意,'__name__ =='__main __''的作用意味着你正在執行模塊。 –

0

一種解決方案是提供__name__明確在你exec ution字典:

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

安全嗎?我的意思是來自問題的代碼和從命令行運行代碼的唯一區別只有這個修復?我知道有更多的鍵像'__doc__',但是這個修補程序對於使它看起來像命令行中的代碼至關重要? –