Python:在“ exec”环境中出现奇怪的“ NameError:名称……未定义”


问题内容

我有信心至少对Python的作用域系统有一些基本的了解。现在我遇到了一个错误,不幸的是,到目前为止,我什至无法编写好的代码片段进行复制。我试图在一个新的小项目中重现它,但是一切都按我期望的那样工作:-/

我只能描述自己的工作,希望有人能够检测到某种模式,并告诉我这里可能出了什么问题。

首先,有一个x.py实现类的python文件X

在其他一些python文件中,有以下字符串:

code="""
...
from x import X
...
class Y(X): # does not crash here, ...
    def __init__(self):
        X.__init__(self) # ... but here
        ...
foo=Y()
"""

您可以假定python能够找到该x模块。在某个地方,我尝试执行该操作:

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

现在我得到了NameError。它告诉我X在尝试调用其构造函数时未定义。显然,上面已经定义了几行。

如果我Y.__init__以添加from x import X为第一行进行修改,则可以正常工作。但是,为什么我还要在那里再次将其导入?

如前所述,实际代码更加复杂,并且可以执行更多操作。不幸的是,我的帖子甚至没有显示实际导致问题的部分。但是也许您有一些一般性的想法,如何获得这样的行为。


问题答案:

这只是一个猜测,因为您没有给我们展示足够的代码,而您给我们展示的内容实际上并没有重现问题,但是……

如果您在exec函数内部执行此操作,则locals()globals()将有所不同。在这种情况下,代码将像在类定义中一样被执行。因此,就像您这样做:

class _:
    from x import X
    class Y(X): # does not crash here, ...
        def __init__(self):
            X.__init__(self) # ... but here
    foo=Y()
del _

(我以前认为您
必须在Y()之外执行类似的操作exec,但是user2357112的回答使我确信这是不必要的。)

如果是您的问题,您可以通过致电exec(code, globals(), globals())或来解决exec(code, locals(), locals())。(当然,哪一个合适,取决于您实际上要尝试执行的操作,而您没有告诉我们。)