在全局环境中使用exec定义函数

时间:2015-04-23 01:56:59

标签: python function python-2.7

我有一个函数,在调用时,应该使用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

我有点期待,所以我根据docsexec(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

我觉得我错过了一些非常明显的东西,但我无法弄明白。任何帮助表示赞赏。

谢谢。

2 个答案:

答案 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()

尝试注释出的对比线。