【发布时间】:2011-04-07 21:00:09
【问题描述】:
我遇到了一个奇怪的子类 numpy.ndarray 问题,感觉就像
Values of instance variables of superclass persist across instances of subclass
但是我无法完全理解或使其适用于我的示例。
通读 Slightly more realistic example - attribute added to existing array 我正试图做到这一点。我想在数组中添加一个 attrs 属性来保存字典中的单位等信息。
这是我所拥有的:
import numpy
class dmarray(numpy.ndarray):
def __new__(cls, input_array, attrs={}):
obj = numpy.asarray(input_array).view(cls)
obj.attrs = attrs
return obj
def __array_finalize__(self, obj):
# see InfoArray.__array_finalize__ for comments
if obj is None:
return
self.attrs = getattr(obj, 'attrs', {})
然后使用它并演示问题
a = dmarray([1,2,3,4])
b = dmarray([1,2,3,4])
a.attrs['foo'] = 'bar'
print(b.attrs)
#{'foo': 'bar'}
b.attrs is a.attrs
# True # hmm....
所以 b 正在拾取我不想要的属性。烦人的是,如果你这样做,它工作得很好:
from datamodel import *
a = dmarray([1,2,3,4], attrs={'foo':'bar'})
b = dmarray([1,2,3,4])
b.attrs
# {}
那么我到底要如何让这个 dmarray 按我想要的方式工作呢?
编辑: 好的,所以这似乎解决了问题,但我不明白为什么。那么让我们把问题改成这是在做什么以及为什么会起作用?
class dmarray(numpy.ndarray):
def __new__(cls, input_array, attrs=None):
obj = numpy.asarray(input_array).view(cls)
return obj
def __init__(self, input_array, attrs=None):
if attrs == None:
attrs = {}
self.attrs = attrs
因此,通过从 __new__() 中删除 kwarg 并将其放入 __init__() 即可。我只是将其作为“它可能会起作用”来尝试
a = dmarray([1,2,3,4])
b = dmarray([1,2,3,4])
a.attrs['foo'] = 'bar'
b.attrs
# {}
【问题讨论】:
-
一位同事提到他认为问题可能是 .view(),嗯,我还可以在那里使用什么?
-
听起来有点像this important warning。
-
谢谢,问题当然出在 attrs={} 上,但以一种出乎我意料的方式表现出来,我一直在查看 .copy()