为什么不执行一个子函数的函数?

看起来你不能在一个具有子function的函数中使用exec …

任何人都知道为什么这个Python代码不起作用? 我在test2的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() 

编辑:我缩小了在子function有一个function的错误。 它与raise关键字无关。

正确。 除非指定上下文,否则不能在具有子function的函数中使用exec。 从文档:

如果在函数中使用exec,并且函数包含带有自由variables的嵌套块,则编译器将引发SyntaxError,除非该exec明确指定exec的本地名称空间。 (换句话说,“exec obj”将是非法的,但是“exec obj in ns”将是合法的。)

如果不是星期天晚上,我可能会理解这个理由。 现在,下一个问题:你为什么使用exec? 这是非常less的需要。 你说你有一个很好的理由。 我对此感到怀疑。 ;)如果你有一个很好的理由,我会告诉你解决方法。 😛

噢,好吧,无论如何,

 def test2(): """Test with a subfunction.""" exec 'print "hi from test2"' in globals(), locals() def subfunction(): return True 

尽pipe在Python中它看起来有点像本地variables存储在字典locals() ,但通常不是。 相反,他们大多存储在堆栈上并通过索引来访问。 这使得本地variables的查找速度比每次查询字典时都快。 如果你使用locals()函数,那么你得到的是一个从所有局部variables创build的新字典,这就是为什么分配给locals()通常不起作用的原因。

这种情况有几个例外:

当你在一个函数内部使用一个非限定的exec Python会closures优化,并为局部variables使用一个真正的字典。 这意味着你可以在exec内部创build或者更新variables,但是这也意味着在这个函数中所有的局部variables访问都会运行得更慢。

另一个例外是,当嵌套函数时,内部函数可以访问外部函数范围中的局部variables。 当它这样做时,variables被存储在“单元”对象中,而不是被存储在堆栈上。 不pipe是从内部函数还是外部函数访问它们,额外的间接级别都会使所有使用范围variables的操作变慢。

你遇到的问题是,通常存储局部variables的这两个例外是不兼容的。 您不能将variables存储在字典中并通过单元格引用同时访问。 Python 2.x通过禁止exec来解决这个问题,即使在这种情况下,你也不想使用任何作用域variables。

在修改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 ,我不认为这是一个错误。

这是一个相当有趣的情况:

 >>> 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包含一个自由variables,而且由于在Python 2中, exec理论上可以修改包含范围中的局部variables,所以不可能决定variables是应该从全局variables还是从全局variables父函数范围。 Python的禅宗之一的诗句是“面对模棱两可,拒绝猜测的诱惑”。 这就是Python 2所做的。

现在的问题是:这个未绑定的variables是什么? 那么,这是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 

尽pipeNone不能被分配,并且在字节码中被认为是一个常量 ,但是这个buggyparsing器认为这是一个未绑定的variables。

但是,如果你用1代替它,它没有问题的工作:

 >>> def test2(): ... exec('print "hi from func"') ... def subfunction(): ... return 1 ... >>> 

为了避免这个错误,请明确指定要被exec使用的全局variables和可能的局部variables,例如:

 >>> def test2(): ... exec 'print "hi from test2"' in {} ... def subfunction(): ... return None ... >>> 

在Python 3中, exec只是一个简单的函数,并不是由parsing器或字节码编译器专门处理的。 在Python 3中exec不能重新绑定函数本地名,因此这个SyntaxError和模糊不存在。


Python 2 vs 3兼容性的一个奇怪的例子是Python 2.7的文档说明了这一点

表单exec(expr, globals)相当于exec expr in globals exec(expr, globals, locals)forms相当于exec expr in globals, localsexec的元组forms提供了与Python 3的兼容性,其中exec是一个函数而不是语句。

元组表单并不总是100%兼容,因为在嵌套函数的函数中处理exec有一个错误(issue 21591) ; 直到Python 2.7.8以下代码可能会引发exception:

 def func(): exec('print "hi from test2"', {}) def subfunction(): return None 

这已经在Python 2.7.9中解决了,不再抛出。

这个错误对我来说似乎相当明显:

 SyntaxError: unqualified exec is not allowed in function 'test2' it contains a nested function with free variables 

有关更多信息,请参见pep 227: http : //www.python.org/dev/peps/pep-0227/