我有一个函数,在调用时,应该使用exec
定义另一个函数,并使这个新函数可用于主程序。 mwe如下。
主程序:
#!/usr/bin/python
from ext import makeF
makeF()
sayA()
外部模块:
def makeF():
script="def sayA():\n\tprint 'Aah'"
exec(script)
sayA()
return
我想要的是能够从主程序调用内部函数sayA()
,所以在这个例子中输出应该是
Aah
Aah
但它会返回
Aah
Traceback (most recent call last):
File "mwe.py", line 5, in <module>
sayA()
NameError: name 'sayA' is not defined
我有点期待,所以我根据docs将exec(script)
行替换为exec(script,globals)
,但我得到了
Traceback (most recent call last):
File "mwe.py", line 4, in <module>
makeF()
File "/home/tomas/tests/ext.py", line 3, in makeF
exec(script,globals,locals)
TypeError: exec: arg 2 must be a dictionary or None
我觉得我错过了一些非常明显的东西,但我无法弄明白。任何帮助表示赞赏。
谢谢。
答案 0 :(得分:3)
您已在makeF
内创建了该函数,因此在函数外部的外部模块范围内甚至无法看到该函数。
如果您想从main return sayA
:
def makeF():
script="def sayA():\n\tprint('Aah')"
exec(script)
return sayA
然后在主要:
f = makeF()
f()
要在python3中获得相同的行为,其中exec不再是语句而是函数,您可以使用带有dict的lambda:
def makeF():
d = {}
"sayA = lambda: print('Aah')"
exec("sayA = lambda: print('Aah')",d)
return d["sayA"]
from ext import makeF
f = makeF()
f()
答案 1 :(得分:3)
globals和locals()是函数,而不是字典(尽管它们返回字典)。
但是,你试图调用它的方式,sayA正在locals()中定义。把它留下来。
我的版本:
def makeF():
script="def sayA():\n\tprint 'Aah'"
#exec script in globals()
exec(script, globals())
#exec(script, globals(), locals())
sayA()
print globals()
print locals()
makeF()
sayA()
尝试注释出的对比线。