[英]Python exec() NameError: name 'o' is not defined
[英]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.