在Linux下使用python 3.6和numpy 1.12.1时,我偶然发现了奇怪的行为。
我有一个self.count
属性,我用np.array([0.0, 0.0, 0.0])
初始化。我希望self.count
的行为与任何其他属性一样,并且每个类实例都有自己的值。
但是,在下面的代码中,当我使用
时使用addPixel
方法
self.count += (1.0, 1.0, 1.0)
对于类CumulativePixel
的所有实例,self.count属性都会增加。我想知道为什么会发生这种情况以及为什么我这样做时会修复:
self.count = self.count + (1.0, 1.0, 1.0)
代替。
import numpy as np
class CumulativePixel(object):
'''
class adds rgb triples and counts how many have been added
'''
def __init__(self, rgb = (0,0,0), count=np.array([0.0, 0.0, 0.0]) ):
'''
Constructor
rgb sum is stored as two values. The integer part plus float part
they are stored in a 2x3 matrix where the first row are integer
parts and the second row are float parts. The code always tries to
make sure that float part is below 1.0
'''
self.rgb = np.array( [np.fmod(rgb, (1,1,1)).astype(float), (rgb - np.fmod(rgb, (1,1,1)))] )
self.count = count
@staticmethod
#for now only works for positve numbers
def _pixeladdition (disassembled, rgb):
disassembled += np.array( [np.fmod(rgb, (1,1,1)).astype(float), (rgb - np.fmod(rgb, (1,1,1)))] )
fpart = np.fmod(disassembled[0], (1,1,1))
overflowpart = disassembled[0]-fpart
disassembled[0]=fpart
disassembled[1]+=overflowpart
return disassembled
def addPixel(self, rgb):
self.rgb = self._pixeladdition(self.rgb, rgb)
# += would globalize self.count into all instances! why ???
self.count = self.count + (1.0, 1.0, 1.0)
def getAvgPixel(self, multiply = (1.0, 1.0, 1.0), add = (0.0, 0.0, 0.0), roundpx = False):
if 0.0 in self.count: return (0.0, 0.0, 0.0)
averagepixel = np.sum(self._pixeladdition((self.rgb/self.count), add)*multiply, axis=0)
if roundpx: averagepixel = np.round(averagepixel).astype(int)
return averagepixel
def getSums(self):
return np.sum(self.rgb, axis=0)
def __str__(self):
return "count: " + str(self.count) + " integers: " + str(self.rgb[1].tolist())+ " floats: " + str(self.rgb[0].tolist())
def __repr__(self):
return "CumulativePixel(rgb = " + str(tuple(np.sum(self.rgb, axis=0))) + ", count=" + str(self.count) +")"
修改 我创建了这个类的实例(在另一个类中),如下所示:
self.pixeldata = [CumulativePixel() for i in range(self.imagewidth*self.imageheight)]
答案 0 :(得分:1)
这是一个常见的错误,最常见的情况是使用列表作为函数的默认值。
pdf()
初始化类时,会创建一次此数组。因此,所有实例共享相同的count=np.array([0.0, 0.0, 0.0])
属性,相同的数组。他们没有得到新的阵容。
执行create
时,您可以就地修改它。
使用self.create +=...
,您可以创建一个新数组,因此一个实例中的更改不会影响其他实例。
做这样的事情是个好习惯:
self.create = self.create + ...
现在,默认值将是新鲜的,每个实例都是唯一的。