Python导入行为和';非类型';对象没有属性
有人能澄清以下行为吗。我在一段更大的代码中遇到了它,但我创建了一个最小的示例 文件Python导入行为和';非类型';对象没有属性,python,python-import,Python,Python Import,有人能澄清以下行为吗。我在一段更大的代码中遇到了它,但我创建了一个最小的示例 文件untitled0.py由以下代码组成: import numpy as np class A: def f(self,x): return np.diag(x) import untitled0 as u0 import numpy as np a=u0.A() print a.f([1]) 文件untitled1.py由以下代码组成: import numpy as np class
untitled0.py
由以下代码组成:
import numpy as np
class A:
def f(self,x):
return np.diag(x)
import untitled0 as u0
import numpy as np
a=u0.A()
print a.f([1])
文件untitled1.py
由以下代码组成:
import numpy as np
class A:
def f(self,x):
return np.diag(x)
import untitled0 as u0
import numpy as np
a=u0.A()
print a.f([1])
输出简单,[[1]]打印在屏幕上。现在假设您已经用大量计算工作创建了a
(a的一个实例),并且继续编写脚本,并且不想一直重新计算。然后我通常只需注释掉创建行(因为对象a已经存在于python shell中),即:
但是,当我运行此脚本时,会导致以下错误:
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'
UMD已删除:untitled0
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“C:\WinPython-64bit-2.7.5.1\python-2.7.5.amd64\lib\site packages\spyderlib\widgets\externalshell\sitecustomize.py”,第523行,在runfile中
execfile(文件名、命名空间)
文件“M:\..\untitled1.py”,第12行,在
打印a.f([1])
文件“untitled0.py”,第12行,在f中
返回np.diag(x)
AttributeError:“非类型”对象没有属性“diag”
由于某些原因,untitled0.py
中没有定义np
。有人能解释一下发生了什么吗?提示行是“UMD已删除…”。您可能正在使用Spyder IDE,下面描述了这种非标准行为:
现在的另一个问题是模块untitled0.py已卸载(并重新加载)。但是,您先前存在的实例a
有一个类,该类就是模块的旧副本中存在的类。因此它的方法f()
调用旧版本的代码。这里的问题是模块的旧副本被垃圾收集:这意味着(奇怪的是)Python已经用无替换了所有全局名称。这就是为什么您最终会查找np.diag()
——但会崩溃,因为此时np
没有
为什么它用无替换所有全局变量???这是一个非常古老的原因:因为它会创建引用循环,很久以前,这种循环用于创建内存泄漏。从那以后就没有清理过
我很抱歉没有关于如何避免这个问题的具体建议,但我希望这足以解释问题的原因。我想应该与Spyder的同事进行进一步的讨论,在那里你应该报告问题以及它是如何出现的。提示行“UMD已删除…”。您可能正在使用Spyder IDE,下面描述了这种非标准行为:
现在的另一个问题是模块untitled0.py已卸载(并重新加载)。但是,您先前存在的实例a
有一个类,该类就是模块的旧副本中存在的类。因此它的方法f()
调用旧版本的代码。这里的问题是模块的旧副本被垃圾收集:这意味着(奇怪的是)Python已经用无替换了所有全局名称。这就是为什么您最终会查找np.diag()
——但会崩溃,因为此时np
没有
为什么它用无替换所有全局变量???这是一个非常古老的原因:因为它会创建引用循环,很久以前,这种循环用于创建内存泄漏。从那以后就没有清理过
我很抱歉没有关于如何避免这个问题的具体建议,但我希望这足以解释问题的原因。我想应该与Spyder的同事进行进一步的讨论,你应该在哪里报告问题以及它是如何出现的。当你这样做时
a.f([1])
评论时
#a = u0.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)
当你这样做的时候
a.f([1])
评论时
#a = u0.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)
您如何调用此代码?您使用的是哪种Python环境?您可以执行
$pip freeze
以查看Python环境中是否安装了numpy
。我正在使用winpython 2.7.5.1中的spyder ide。在spyder中,脚本在python shell(不是ipython,而是普通shell)中启动,并且已经导入了nympy和scipy。Numpy是绝对安装的,因为我可以创建创建Numpy数组的脚本,并在其上使用Numpy例程。您如何调用此代码?您使用的是哪种Python环境?您可以执行$pip freeze
以查看Python环境中是否安装了numpy
。我正在使用winpython 2.7.5.1中的spyder ide。在spyder中,脚本在python shell(不是ipython,而是普通shell)中启动,并且已经导入了nympy和scipy。Numpy是绝对安装的,因为我可以创建创建Numpy数组的脚本并在其上使用Numpy例程。您的诊断是错误的,如果问题是A
实例,解释器会抱怨f
方法,stacktrace会非常不同。您的诊断是错误的,如果问题是A
实例,那么解释器会抱怨f
方法,stacktrace将非常不同。