Python exec 的函数链产生 NameError

考虑以下脚本,它用于exec定义两个函数,其中一个调用另一个:


def run_code():

  code = """

def foo():

  print('foo')

  return 1


def bar():

  print('bar calls foo')

  return 1 + foo()


result = bar()

"""


  exec(code, globals(), locals())

  print('Result: {}'.format(locals()['result']))


run_code()

我希望看到以下输出:


bar calls foo

foo

Result: 2

但相反,我得到以下输出+堆栈跟踪:


bar calls foo

Traceback (most recent call last):

  File "minimal.py", line 17, in <module>

    run_code()

  File "minimal.py", line 14, in run_code

    exec(code, globals(), locals())

  File "<string>", line 10, in <module>

  File "<string>", line 8, in bar

NameError: name 'foo' is not defined

有趣的是,如果将 的内容run_code移至模块级别,那么它就可以正常工作。但是,如果我随后用新的空字典替换globals()or locals(),它会再次中断。我也知道,放进def foo体内bar就能发挥作用。


为什么会发生此错误?正确的解决方法是什么?


(我知道这exec通常会让人皱眉。我使用它是有充分理由的。)


梵蒂冈之花
浏览 130回答 2
2回答

不负相思意

从文档中:如果提供的话,局部变量可以是任何映射对象。请记住,在模块级别,全局变量和局部变量是相同的字典。如果 exec 获取两个单独的对象作为全局对象和局部对象,则代码将像嵌入在类定义中一样执行。并且类定义不会创建封闭范围,请注意,这就是为什么您不能在不使用 的情况下从另一个方法调用方法self。所以只要把字典传过去就可以了globals()。或者将两个相同的字典传递给两个参数。In [4]: def run_code():   ...:     code = """   ...: def foo():   ...:   print('foo')   ...:   return 1   ...:   ...: def bar():   ...:   print('bar calls foo')   ...:   return 1 + foo()   ...:   ...: result = bar()   ...: """   ...:     namespace = {}   ...:     exec(code, namespace)   ...:     print('Result: {}'.format(namespace['result']))   ...:In [5]: run_code()bar calls foofooResult: 2

元芳怎么了

code = """&nbsp;&nbsp;def foo():&nbsp; print('foo')&nbsp; return 1def bar():&nbsp; global foo;&nbsp; print('bar calls foo')&nbsp; return 1 + foo()result = bar()"""def run_code():&nbsp; &nbsp; exec(code, globals(), locals())&nbsp; &nbsp; print('Result: {}'.format(locals()['result']))run_code()输出:bar calls foofooResult: 2
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python