任何人都可以澄清以下行为。我在一段更大的代码中遇到了它,但我创建了一个最小的例子
文件untitled0.py
包含以下代码:
import numpy as np
class A:
def f(self,x):
return np.diag(x)
文件untitled1.py
包含以下代码:
import untitled0 as u0
import numpy as np
a=u0.A()
print a.f([1])
输出简单,并在屏幕上打印[[1]]。现在假设您已经创建了a
(A的实例)并且需要大量的计算工作并继续编写脚本并且不想一直重新计算。我通常做的只是注释掉创建行(因为对象a已经存在于你的python shell中),即:。
import untitled0 as u0
import numpy as np
#a=u0.A()
print a.f([1])
但是,当我运行此脚本时会导致错误:
UMD has deleted: untitled0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\WinPython-64bit-2.7.5.1\python-2.7.5.amd64\lib\site-packages\spyderlib\widgets\externalshell \sitecustomize.py", line 523, in runfile
execfile(filename, namespace)
File "M:\....\untitled1.py", line 12, in <module>
print a.f([1])
File "untitled0.py", line 12, in f
return np.diag(x)
AttributeError: 'NoneType' object has no attribute 'diag'
由于某些原因np
未在untitled0.py
内定义。谁能解释发生了什么?
答案 0 :(得分:0)
“UMD已删除...”这一行是提示。您可能正在使用Spyder IDE,此处描述了这种非标准行为:Spyder - UMD has deleted: module
现在另外一个问题是unitled0.py模块已被卸载(并重新加载)。但是,预先存在的实例a
具有一个类,该类是模块的旧副本中存在的类。因此,它的方法f()
调用代码的旧版本。这里的问题是模块的旧副本是垃圾收集的:这意味着(奇怪的是)Python已经用None替换了所有全局名称。这就是您最终查找np.diag()
---但崩溃的原因,因为此时np
为无。
为什么用None替换所有全局变量?这是一个非常古老的原因:因为它创建了引用循环,而且很久以前这样的循环用于创建内存泄漏。从那时起它就没有被清理过。
我很抱歉没有就如何避免这个问题提出具体的建议,但我希望这足以解释它是如何以及为什么的。我想进一步的讨论应该与Spyder的人一起讨论,你应该在那里报告问题以及它是如何出现的。
答案 1 :(得分:-1)
当你做
时a.f([1])
评论时
#a = u0.A()
发生的事情是a没有实例化。当a不存在时,无法调用其方法。这就是为什么解释器抛出“NoneType”属性没有名为diag的方法。而不必每次都重新计算结果,尝试通过改变f的行为将结果存储在a中;例如
class A:
def f(self,no):
self.result = np.diag(no)
return self.result
然后再做
a = u0.A()
#use a
a.f(some_list)