[英]Python AST exec “… is not defined” error on recursive function
我遇到了这个错误
def test_rec():
import ast
exec(compile(ast.fix_missing_locations(ast.parse("""
def fact(n):
return 1 if n == 0 else n * fact(n - 1)
print(fact(5))
"""), "<string>", "exec")))
这会产生这个错误,这很奇怪
Traceback (most recent call last):
File "/Users/gecko/.pyenv/versions/3.9.0/envs/lampy/lib/python3.9/site-packages/nose/case.py", line 198, in runTest
self.test(*self.arg)
File "/Users/gecko/code/lampycode/tests/test_let_lang.py", line 6, in test_rec
exec(compile(ast.fix_missing_locations(ast.parse("""
File "<string>", line 4, in <module>
File "<string>", line 3, in fact
NameError: name 'fact' is not defined
如果我在 REPL 中复制并粘贴相同的代码,它可以正常工作
>>> def fact(n):
... return 1 if n == 0 else n * fact(n - 1)
...
>>> print(fact(5))
120
>>>
有任何想法吗?
我可以进一步减少问题这里是最小的例子,这会溢出堆栈但它给了我同样的未定义错误
def test_rec3():
exec("""
def f():
f()
f()
""")
--
第二次编辑,更进一步,这只发生在函数内部
这有效
exec("""
def f(n):
print("end") if n == 1 else f(n-1)
f(10)""")
但这给了我与上面相同的错误
def foo():
exec("""
def f(n):
print("end") if n == 1 else f(n-1)
f(10)""")
foo()
如果将exec
与默认局部变量一起使用,则绑定局部变量是未定义的行为。 这包括def
,它将新的 function 绑定到局部变量。
此外,在exec
中定义的函数不能访问闭包变量, fact
就是这样。
避免这些问题的最好方法是不使用exec
。 第二种最佳方式是提供显式命名空间:
namespace = {}
exec(whatever, namespace)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.