Я пытаюсь создать новый объект класса внутри этого же класса, однако вместо создания нового объекта он просто создает новую ссылку на тот же объект, в котором я сейчас работаю.
Таким образом, если я изменяю значение одного объекта, он также меняет значение и в другом - хотя у меня, вероятно, должно быть 2 совершенно разных объекта.
Использование метода copy.deepcopy()
устраняет проблему со ссылкой, но я думаю, что он должен работать по-другому.
Как мой код ведет себя в этой конкретной реализации?Есть ли причина для этого создавать поверхностную копию того же самого объекта, даже если код, вероятно, должен создать его новый экземпляр?
Это слегка уменьшенный фрагмент кода:
class Vec4():
def __init__(self, x = 0, y = 0, z = 0, w = 0):
self.values = [x,y,z,w]
def __str__(self):
return str(self.values[0]) + ' ' + str(self.values[1]) + ' ' + str(self.values[2]) + ' ' + str(self.values[3])
def setValue(self, index, value):
self.values[index] = value
def scalar(self, vector):
"""returns the result of the scalar multiplication"""
result = 0
for u in range(4):
result += self.values[u] * vector.values[u]
return result
class Matrix4():
def __init__(self, row1 = Vec4(), row2 = Vec4(), row3 = Vec4(), row4 = Vec4()):
self.m_values = [row1,row2,row3,row4]
self.trans_values = [Vec4(),Vec4(),Vec4(),Vec4()]
self.set_transp_matrix()
def __str__(self):
return self.m_values[0].__str__() + '\n' + self.m_values[1].__str__() + '\n' + self.m_values[2].__str__() + '\n' + self.m_values[3].__str__()
def setIdentity(self):
identity = Matrix4(Vec4(1,0,0,0),
Vec4(0,1,0,0),
Vec4(0,0,1,0),
Vec4(0,0,0,1))
for i in range(4):
for j in range(4):
self.m_values[i].values[j] = identity.m_values[i].values[j]
def set_transp_matrix(self):
for t in range(4):
for s in range(4):
self.trans_values[t].values[s] = self.m_values[s].values[t]
def get_trans_matrix(self):
return self.trans_values[0].__str__() + '\n' + self.trans_values[1].__str__() + '\n' + self.trans_values[2].__str__() + '\n' + self.trans_values[3].__str__()
def mulM(self, m):
print(self, "\n")
matrixResult = Matrix4()
print(matrixResult, "\n")
for row in range(4): # rows of self
for element in range(4):
value = self.m_values[row].scalar(m.trans_values[element])
matrixResult.m_values[row].setValue(element, value)
return matrixResult
class ScaleMatrix(Matrix4):
def __init__(self, m_scale = Vec4(1,1,1), *args, **kwargs):
super(ScaleMatrix, self).__init__(*args, **kwargs)
self.m_scale = m_scale
self.update()
def getScale(self):
"""Returns the scale vector, only x, y and z are relevant"""
return self.m_scale
def setScale(self, v):
"""Sets the scale vector, only x, y and z are relevant"""
self.m_scale = v
self.update()
def update(self):
"""Calculates the scale matrix"""
self.setIdentity()
for i in range(3):
self.m_values[i].values[i] = self.getScale().values[i]
return self
if __name__ == "__main__":
#Simple Constructor and Print
a = Vec4(1,2,3,4)
b = Vec4(5,6,7,8)
c = Vec4(9,10,11,12)
d = Vec4(13,14,15,16)
A = Matrix4(a, b, c, d)
D = ScaleMatrix()
D.setScale(Vec4(3, 4, 5, 1))
print(D.mulM(A))
Проблема в классе Matrix4
, метод mulM()
, где matrixResult = Matrix4()
должен создать новый экземпляр Matrix4()
(где все значения Vec4()
должны быть 0
) вместо простого копирования self
объект.Вывод print
показывает следующее:
3 0 0 0
0 4 0 0
0 0 5 0
0 0 0 1
3 0 0 0
0 4 0 0
0 0 5 0
0 0 0 1
3 6 51 672
20 64 508 6688
45 140 1170 15340
13 40 334 4396
Таким образом, вторая матрица не должна быть равна первой.Однако проблема не возникает, если я создаю обычный объект Matrix4()
вместо объекта ScaleMatrix()
, который расширяет Matrix4()
в самом конце фрагмента кода выше.
Python v.3.6.4