2012-08-29 66 views
8

我對python相當陌生,現在一直在玩它。我一直玩的內置compile()函數,以及marshal和內置exec()。我注意到了一些我不能找到答案的東西。請看下面的代碼:Python exec()的編組代碼對象

with open('simple.py', 'r') as f: 
    code = f.read() 
exec code 

然而,當編譯成通過compile()代碼對象,通過marshal.dump()系列化,保存到一個文件,然後閱讀:

#!/usr/bin/python 

def foo(): 
    print "Inside foo()..." 

def main(): 
    print "This is a simple script that should count to 10." 

    for i in range(0, 10): 
     print "This is iteration number", i 

    foo() 

if __name__ == "__main__": 
    main() 

當通過類似運行也能正常工作從文件中,通過marshal.load()進行反序列化,並使用exec()運行,結果爲NameError,指出全局名稱foo未定義。

我看過dir()給出的輸出,當我的代碼爲import()時,我可以看到它的定義爲foo()。我還注意到,在反序列化的代碼對象上使用dis.dis()(通過marshal.load()讀取),我看到的唯一情況是LOAD_NAMECALL_FUNCTION對於main()(而不是像exec 'import %s' % modname那樣做,然後做dis.dis(sys.modules[modname]),這會給你如預期的那樣進行整個拆卸)。

我正確的是有某種查詢表,import()諮詢得到這些地址? (爲了記錄,我檢查了http://svn.python.org/projects/python/trunk/Lib/py_compile.py以及我在通過py_compile.compile()生成的字節碼和內置的compile()imp.get_magic()以及32位時間戳中可以看到的唯一差別。如果存在這樣的表格,有沒有一種很好的方法來諮詢它?

謝謝!

+1

什麼是通過'marshal.dump()'序列化?文本文件? – Claudiu

+0

該腳本的代碼對象通過'compile()'生成。 – user1633448

+0

你是什麼意思?以下內容似乎有效: with open('simple.py','r')as f: code = f.read() with open('simple.mash','w')as f: marshal.dump(代碼F) 開放( 'simple.mash', 'R')爲f: 碼= marshal.load(F) EXEC代碼 – Dhara

回答

0

此腳本成功地執行您的simple.py代碼3次。這是否澄清了什麼?或者我誤解了你的問題?

# from original example 
with open('simple.py', 'r') as f: 
    code = f.read() 
exec(code) 
# compile and run again 
a = compile(code, "simple_compiled_this_file_not_created", "exec") 
exec(a) 
# marshal and unmarshal 
import marshal 
f = open("./marshalfoo.bin", "wb") 
marshal.dump(a,f) 
f.close() 
b = marshal.load(open("./marshalfoo.bin", "rb")) 
exec(b) 
+1

有趣。所以我能夠根據您的代碼追蹤我的問題。看起來,如果我嘗試在函數內部執行exec()代碼,它會失敗(例如,在運行compile()後,我調用一個名爲runme()的函數,它實際上調用了exec ()'在結果代碼對象上)。更有趣的是,如果我從'compile()'調用'exec()'的範圍,然後調用'runme()'就可以了。所以它肯定是一個範圍問題。 – user1633448

+1

對於任何關心的人,我通過將simple.py內的代碼放在自定義類(我稱之爲Simple)中,然後在'if __name__ ==「__main __」'doing's = Simple ()'和's.main()'。之後,代碼似乎在任何範圍內都能正常工作。 – user1633448