2012-06-27 55 views
3

试图寻找该网站,但无法找到一个答案,我的问题:分级命名空间

可以说我有一个模块,名为mymodule.py包含:

def a(): 
    return 3 

def b(): 
    return 4 + a() 

然后以下作品:

import mymodule 
print(mymodule.b()) 

然而,当我尝试动态定义模块内容:

import imp 

my_code = ''' 
def a(): 
    return 3 

def b(): 
    return 4 + a() 
''' 

mymodule = imp.new_module('mymodule') 
exec(my_code, globals(), mymodule.__dict__) 
print(mymodule.b()) 

然后失败的函数B():

Traceback (most recent call last): 
File "", line 13, in <module> 
File "", line 6, in b 
NameError: global name 'a' is not defined 

我需要一种方法来保存分级名字空间模块搜索,这似乎除非模块驻留在磁盘发生故障。

任何线索至于有什么区别?

谢谢, Rob。

回答

3

你很近。你需要告诉EXEC在不同的命名空间的工作,像这样(见注在底部蟒蛇3.X):

exec my_code in mymodule.__dict__ 

完整的示例:

import imp 

my_code = ''' 
def a(): 
    return 3 

def b(): 
    return 4 + a() 
''' 

mymodule = imp.new_module('mymodule') 

exec my_code in mymodule.__dict__ 
print(mymodule.b()) 

此说,我没有用这之前,所以我不确定是否有任何奇怪的副作用,但它看起来对我有用。

此外,在Python文档这里有关于一个小的Blurb“EXEC在...”:http://docs.python.org/reference/simple_stmts.html#the-exec-statement

更新

原来的企图没有正常工作的原因是你路过你的目前的模块的globals()字典,它与你的新模块应该使用的globals()不同。

此exec线也可以(但并不像漂亮 '在EXEC ...' 风格):

exec(my_code, mymodule.__dict__, mymodule.__dict__) 

更新2:由于Exec现在是在Python 3的功能。 x,它没有'exec in ...'风格,所以必须使用上面的行。

+0

是否有一个python 3.x版本的“exec ... in”? 似乎无法在exec()函数中找到它。 谢谢 – rbairos

+0

它看起来不像它...看到我的更新,'不太漂亮'的版本应该在3.x中为你工作(我还没试过,所以让我知道它是否有效) –

+0

好吧,我测试过'exec(my_code,mymodule .__ dict__,mymodule。__dict __)'在python3中,它似乎工作正常。我已经更新了我的答案以反映这一点。 –

0

这不是exec()的设计目的。 exec()实际上并没有将其运行的代码“放入”任何模块 - 它在exec()被调用的模块空间中运行。

+0

那么有没有其他办法可以重现我需要的模块行为?谢谢 – rbairos