Linux에서 python 3.6 및 numpy 1.12.1을 사용할 때 이상한 동작이 발생했습니다.이 numpy 속성이 인스턴스간에 갑자기 공유되는 이유
나는 np.array([0.0, 0.0, 0.0])
으로 초기화하는 self.count
속성을 가지고 있습니다. 나는 self.count
이 다른 속성처럼 행동하고 클래스 인스턴스 당 자체 값을 가질 것이라고 기대합니다.
그러나, addPixel
방법에 아래의 코드에 나는
self.count += (1.0, 1.0, 1.0)
self.count 속성이 클래스 CumulativePixel
의 모든 인스턴스 증가됩니다를 사용하는 경우. 왜 이런 일이 일어나고 내가 할 때 문제가 해결되는 이유를 알고 싶습니다.
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)]
내부 기본값이 사실 특정 값일지라도 많은 라이브러리가 기본값으로 None을 사용하는 이유가 여기 있습니다. 또한 동일한 포인터의 여러 복사본으로 끝나는 목록 곱셈 ([object] * number)을 생각 나게합니다. – evolution