exec为什么不能在具有子功能的功能中工作?

看起来您不能在具有子功能的函数中使用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关键字无关


繁华开满天机
浏览 977回答 3
3回答

慕桂英546537

正确。除非指定上下文,否则不能在具有子功能的函数中使用exec。从文档:如果在函数中使用了exec并且该函数包含带有自由变量的嵌套块,则除非exec显式指定exec的本地名称空间,否则编译器将引发SyntaxError。(换句话说,“ 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

慕田峪4524236

尽管在Python中看起来好像局部变量存储在字典中locals(),但通常不是。相反,它们通常存储在堆栈中,并通过索引进行访问。这使得局部变量查找的速度比每次必须进行字典查找的速度都要快。如果使用该locals()函数,则得到的是从所有局部变量创建的新字典,这就是为什么分配给locals()通常不起作用的原因。此方案有两个例外:当您exec在函数内部使用非限定条件时,Python会关闭优化,并使用真正的字典作为局部变量。这意味着您可以从中创建或更新变量exec,但这也意味着该函数中所有本地变量访问将运行得更慢。另一个例外是,当您嵌套函数时,内部函数可以访问外部函数范围内的局部变量。执行此操作时,变量将存储在“单元”对象中,而不是存储在堆栈中。无论是从内部函数还是外部函数访问范围变量,额外的间接级别都会使作用域变量的使用变慢。您遇到的问题是,通常如何存储局部变量的这两个例外是不兼容的。您不能将变量存储在字典中并同时通过单元格引用进行访问。Python 2.x通过禁止exec来解决此问题,即使在这种情况下,您也不想使用任何作用域变量。

慕神8447489

这是一个很有趣的情况:>>> def func():...&nbsp; &nbsp; &nbsp;exec('print "hi from func"')...&nbsp; &nbsp; &nbsp;def subfunction():...&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return True...&nbsp;&nbsp; File "<stdin>", line 2SyntaxError: unqualified exec is not allowed in function 'func' because&nbsp;it contains a nested function with free variables确实不起作用的原因是它subfunction包含一个自由变量,并且由于在Python 2中,exec理论上可以修改包含范围中的局部变量,因此无法决定该变量是应与全局变量还是与父变量绑定功能范围。Python Zen中的其中一句诗是“面对模棱两可,拒绝猜测的诱惑”。这就是Python 2所做的。现在的问题是:这个自由(未绑定)变量是什么?好吧,是True!实际上,它可以通过None以下方式重现:>>> def func():...&nbsp; &nbsp; &nbsp;exec('print "hi from func"')...&nbsp; &nbsp; &nbsp;def subfunction():...&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return None...&nbsp;&nbsp; File "<stdin>", line 2SyntaxError: unqualified exec is not allowed in function 'test2' because it contains a nestedfunction with free variables即使None无法分配给它,并且在字节码中将其视为常量,但越野车解析器仍认为这是一个未绑定变量。但是,如果您将其替换为1并且可以正常使用,则可以:>>> def test2():...&nbsp; &nbsp; &nbsp;exec('print "hi from func"')...&nbsp; &nbsp; &nbsp;def subfunction():...&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return 1...&nbsp;>>>为避免此错误,请明确指定要使用的全局变量和可能的局部变量exec,例如:>>> def test2():...&nbsp; &nbsp; &nbsp;exec 'print "hi from test2"' in {}...&nbsp; &nbsp; &nbsp;def subfunction():...&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return None...>>>在Python 3中,exec这只是一个简单的函数,没有由解析器或字节码编译器专门处理。在Python 3 exec中无法重新绑定函数本地名称,因此此SyntaxError和歧义不存在。Python 2 vs 3兼容性的一种特殊情况是,尽管Python 2.7文档指出:形式exec(expr, globals)等同于exec expr in globals,而形式exec(expr, globals, locals)等同于exec expr in globals, locals。元组形式exec提供了与Python 3的兼容性,Python 3 exec是函数而不是语句。元组形式并不总是100%兼容的,因为在处理exec带有嵌套函数的in函数中存在一个错误(issue 21591);在Python 2.7.8之前,以下代码可能引发了异常:def func():&nbsp; &nbsp; exec('print "hi from test2"', {})&nbsp; &nbsp; def subfunction():&nbsp; &nbsp; &nbsp; &nbsp; return None这已在Python 2.7.9中修复,并且不再抛出。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python