2010-02-22 123 views
12

鑑於我擁有模塊的代碼對象,我如何獲取相應的模塊對象?如何從Python中的代碼對象生成模塊對象

它看起來像moduleNames = {}; exec code in moduleNames做的東西非常接近我想要的東西。它將模塊中聲明的全局變量返回給字典。但是如果我想要實際的模塊對象,我該如何得到它?

編輯: 它看起來像你可以推出自己的模塊對象。該模塊類型不方便記錄,但你可以做這樣的事情:

import sys 
module = sys.__class__ 
del sys 
foo = module('foo', 'Doc string') 
foo.__file__ = 'foo.pyc' 
exec code in foo.__dict__ 
+0

的首選接入去除點的模塊類型是'types.ModuleType'。 – 2010-02-23 00:09:15

回答

19

爲註釋已經表明,在當今的Python實例的類型不具有內置的名字是首選方式調用通過types模塊標準庫中獲得的類型:

>>> import types 
>>> m = types.ModuleType('m', 'The m module') 

注意這並沒有自動插入sys.modules新模塊:

>>> import sys 
>>> sys.modules['m'] 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
KeyError: 'm' 

這是你必須手工完成一項任務:

>>> sys.modules['m'] = m 
>>> sys.modules['m'] 
<module 'm' (built-in)> 

這可能是重要的,因爲一個模塊的代碼對象正常執行後的模塊添加到sys.modules - 例如,它是這樣完全正確代碼指sys.modules[__name__],如果您忘記了這一步,那將失敗(KeyError)。 這一步,並設置m.__file__因爲你已經在你的編輯後,

>>> code = compile("a=23", "m.py", "exec") 
>>> exec code in m.__dict__ 
>>> m.a 
23 

(或Python的3當量,其中exec是一個函數,如果Python 3的是你使用的當然是什麼; - )是正確的(當然,你通常會通過微妙的手段獲得代碼對象而不是編譯一個字符串,但這對你的問題並不重要;-)。

在舊版本的Python你會使用new模塊,而不是types模塊,使其在開始一個新的模塊對象,但new因爲Python 2.6已被棄用,在Python 3