繁体   English   中英

Python:在'exec'环境中奇怪的“NameError:name ...未定义”

[英]Python: weird “NameError: name … is not defined” in an 'exec' environment

我有信心至少对Python的范围系统有一些基本的了解。 现在我收到一个错误,遗憾的是到目前为止我甚至无法为复制编写好的代码片段。 我尝试在一个新的小项目中重现它,但一切都按照我的预期运行: - /

我只能描述我的所作所为,并希望有人能够检测出一种模式并告诉我这里可能出现的问题。

起初有一个python文件x.py ,它实现了一个类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())来修复它。 (哪一种适当,如果有的话,取决于你实际上想要做什么,当然,你没有告诉我们。)

exec文档

如果exec获得两个单独的对象作为全局变量和局部变量,则代码将被执行,就像它嵌入在类定义中一样。

这有很好的理由,我不会在这里讨论。

类定义中定义的函数不会查看变量分辨率的类定义的范围。 exec code ,它实际上是这样执行的:

class Dummy:
    from x import X
    ...
    class Y(X):
        def __init__(self):
            X.__init__(self)
            ...
    foo=Y()

这意味着这个功能:

def __init__(self):
    X.__init__(self)

没有看到这个变量:

from x import X

即使这一点:

class Y(X):

确实看到了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM