看起来你不能在具有子功能的函数中使用exec ......
任何人都知道为什么这个Python代码不起作用?我在test2的exec上遇到错误。另外,我知道exec的风格并不好,但相信我,我正在使用exec是出于正当的理由。否则我不会用它。
#!/usr/bin/env python
#
def test1():
exec('print "hi from test1"')
test1()
def test2():
"""Test with a subfunction."""
exec('print "hi from test2"')
def subfunction():
return True
test2()
编辑:我将错误缩小到在子功能中使用功能。它与raise关键字无关。
答案 0 :(得分:65)
正确。除非指定上下文,否则不能在具有子函数的函数中使用exec。来自文档:
如果exec用于函数和 function包含一个嵌套块 自由变量,编译器会 除非执行exec,否则引发一个SyntaxError 显式指定本地 exec的命名空间。 (其他 单词,“exec obj”将是非法的, 但是“ns中的exec obj”是合法的。)
如果不是星期天晚上,我很可能会理解这一点。 现在,下一个问题:你为什么使用exec?这很少需要。你说你有充分的理由。我对此持怀疑态度。 ;)如果你有充分的理由我会告诉你解决方法。 :-P
哦,好吧,无论如何:
def test2():
"""Test with a subfunction."""
exec 'print "hi from test2"' in globals(), locals()
def subfunction():
return True
答案 1 :(得分:28)
虽然在Python中看起来有点像局部变量存储在字典locals()
中,但它们通常不是。相反,它们主要存储在堆栈中并通过索引访问。这使得局部变量查找比每次都必须进行字典查找更快。如果您使用locals()
函数,那么您获得的是从所有局部变量创建的新字典,这就是分配给locals()
通常不起作用的原因。
这种情况有几个例外:
当您在函数中使用非限定exec
时,Python会关闭优化并使用真实字典作为局部变量。这意味着您可以从exec
内部创建或更新变量,但这也意味着该函数中的所有本地变量访问都将运行得更慢。
另一个例外是,当您嵌套函数时,内部函数可以访问外部函数作用域中的局部变量。当它执行此操作时,变量存储在“单元”对象中,而不是存储在堆栈中。除了从内部或外部函数访问它们之外,额外的间接级别使得所有范围变量的使用都变慢。
您遇到的问题是,通常存储局部变量的这两个例外是不兼容的。您不能将变量存储在字典中并同时通过单元格引用进行访问。 Python 2.x通过禁止exec来解决这个问题,即使在这样的情况下你也不会尝试使用任何作用域变量。
答案 2 :(得分:6)
这是一个相当有趣的案例:
>>> def func():
... exec('print "hi from func"')
... def subfunction():
... return True
...
File "<stdin>", line 2
SyntaxError: unqualified exec is not allowed in function 'func' because
it contains a nested function with free variables
这不起作用的原因是subfunction
包含一个自由变量,因为在Python 2中,exec
理论上可以修改包含范围内的本地,它将是无法确定变量是否应该从全局或父函数范围绑定。 Python中的一个经文就是&#34;面对歧义,拒绝猜测的诱惑。&#34; 这就是Python 2所做的。
现在的问题是:这个免费(未绑定)变量是什么?好吧,它是True
!
确实可以使用None
重现:
>>> def func():
... exec('print "hi from func"')
... def subfunction():
... return None
...
File "<stdin>", line 2
SyntaxError: unqualified exec is not allowed in function 'test2' because it contains a nested
function with free variables
即使None
无法分配给它,并且在字节码中它被视为常量,但是错误的解析器认为它是一个未绑定的变量。
但是如果你用1
替换它并且它没有问题:
>>> def test2():
... exec('print "hi from func"')
... def subfunction():
... return 1
...
>>>
要避免此错误,请明确指定exec
要使用的全局变量和可能的本地变量,例如:
>>> def test2():
... exec 'print "hi from test2"' in {}
... def subfunction():
... return None
...
>>>
在Python 3中,exec
只是一个简单的函数,并不是由解析器或字节码编译器专门处理的。在Python 3中exec
不能重新绑定函数本地名称,因此这种SyntaxError和歧义不存在。
Python 2与3兼容性中的一个特殊情况是Python 2.7 documentation表示
表单
exec(expr, globals)
相当于exec expr in globals
,而表单exec(expr, globals, locals)
相当于exec expr in globals, locals
。exec
的元组形式提供与Python 3的兼容性,其中exec
是函数而不是语句。
元组表格并不总是100%兼容,因为有a bug in handling of exec
in functions with nested functions (issue 21591);直到Python 2.7.8,以下代码可能抛出异常:
def func():
exec('print "hi from test2"', {})
def subfunction():
return None
这在Python 2.7.9中修复,不再抛出。
答案 3 :(得分:4)
在修改print语句以使用print函数后,在Python 3.1.3中运行良好。
在Python 2.6中,它产生SyntaxError: unqualified exec is not allowed in function 'test2' it contains a nested function with free variables
,我认为这不是一个错误。
答案 4 :(得分:1)
这个错误对我来说似乎很明显:
SyntaxError: unqualified exec is not allowed in function 'test2' it contains a nested function with free variables
有关详细信息,请参阅第227页:http://www.python.org/dev/peps/pep-0227/
答案 5 :(得分:1)
dict
和list
的理解也可以被视为Python 2.7.5上的子功能
例如,这在Python 2.7.5上失败,但在Python 2.7.12上有效:
def func():
exec('print("a")')
(str(e) for e in range(10))
具有:
File "./a.py", line 4
exec('print("a")')
SyntaxError: unqualified exec is not allowed in function 'func' it contains a nested function with free variables
很可能它已在内部编译为字节码中的函数。
TODO查找修复提交。这超出了我的git log --grep
foo。
类似于dict
的理解:
def func():
exec('print("a")', {e:str(e) for e in range(10)})
这是特别糟糕的,因为它是global
参数的通用参数。
也在https://github.com/sphinx-doc/sphinx/issues/5417#issuecomment-421731085
处提出