Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/355.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 巨蟒:怪异“;名称错误:名称。。。“未定义”;在';执行官';环境_Python_Python 3.x - Fatal编程技术网

Python 巨蟒:怪异“;名称错误:名称。。。“未定义”;在';执行官';环境

Python 巨蟒:怪异“;名称错误:名称。。。“未定义”;在';执行官';环境,python,python-3.x,Python,Python 3.x,我有信心至少对Python的范围系统有一些基本的了解。现在我遇到了一个错误,不幸的是,到目前为止,我甚至无法编写一个好的代码片段进行复制。我试图在一个新的小项目中复制它,但一切都按照我的预期进行:-/ 我只能描述我所做的,希望有人能检测到一种模式,并能告诉我这里可能出了什么问题 首先有一个python文件x.py,它实现了一个类x 在其他一些python文件中,有以下字符串: code=""" ... from x import X ... class Y(X): # does not cras

我有信心至少对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())
现在我得到了
namererror
。它告诉我当它试图调用它的构造函数时,
X
没有定义。它显然是在上面几行定义的

如果我修改
Y.\uuuu init\uuuu
并将
从x导入x
添加为第一行,它会工作。但我为什么还要在那里再次导入它呢


如前所述,实际代码更复杂,做的事情也更多。不幸的是,我的帖子甚至没有显示导致问题的部分。但也许你有一些一般性的想法,一个人如何能得到这样的行为。

这只是一个猜测,因为你没有向我们展示足够的代码,你展示的并不是真正重现问题,但是

如果您在函数中执行此操作,则
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 _
(我以前认为您还必须在
exec
之外执行类似
Y()
的操作,但我确信这是不必要的。)

如果这是您的问题,您可以通过调用
exec(code,globals(),globals())
exec(code,locals(),locals())
来解决它。(哪一个是合适的,如果有的话,这取决于你实际上想做什么,当然,你没有告诉我们。)

来自:

如果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):

确实看到了。

只是出于好奇,为什么要调用
X.\uuu init\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuoself)
而不是
我没有立即看到问题,这取决于全局名称空间还发生了什么,但通常你会使用
超级(Y。。。。只是因为我不知道那条捷径。但是使用它并没有改变任何错误:(没有改变Y的定义和崩溃的实例化之间的全局名称空间。两者之间真的没有代码。您所显示的内容没有任何错误。您没有显示的行是什么?我不太明白这一点…为什么
Y()
在一个作用域中工作,在另一个作用域中失败,即使
Y
在两个作用域中引用了相同的类?无论如何,我认为最后一段中的建议可能是正确的。是的,您的猜测是正确的;)太好了,谢谢!我从函数内部调用实代码中的
exec
。在我的测试代码中,它不在函数中,因此globals()和locals()可能返回相同的结果,从而导致
exec
(如您所述)。@abarnet啊,好的,我看到您编辑了我没有遵循的部分答案,所以现在一切都有意义了。@JasonOrendorff:是的,我对user2357112的答案进行了投票,但我的代码已经被接受了,所以我并没有删除它,而是更正了它。我很确定这是不对的,如果是的话,他的代码会被提升,而事实并非如此。这就是为什么我认为一定还有别的事情发生。在我的回答中,我的最佳猜测是,与他的示例不同,他的实际代码是在虚拟类定义完成执行且其作用域消失后,在
exec
之外构造
Y
实例,并且
X
不再可用(或者仅作为不可访问类的class属性可用)。但这只是一个猜测。@abarnert:我不知道你说的“没有提高”是什么意思。拿他的代码,删除
s,用
class x:pass
创建一个
x.py
,然后运行它。也不例外。一切正常。(OP从一开始就承认他的例子不是MCVE,因为他无法简单地再现问题,后来对其进行了编辑,使其更加清晰:“在一个不幸的情况下,我的帖子甚至没有显示导致问题的部分。”)就此而言,只需使用“仿佛”代码,卸下
并运行它。它将很好地执行,您可以验证
Dummy.foo
\uuuu main\uuuu.Dummy.Y
的一个实例。因此,
Y.\uuuu init\uuuu
在执行时可以清楚地看到
X
。@abarnert:我试图通过ideone运行一个简单的示例,但它没有加载。我没有Python 3;你能给我举个例子吗?