回答此问题可获得 20 贡献值,回答如果被采纳可获得 50 分。
<p>我试图在同一个类中创建一个类的新对象,但是它不是创建一个全新的对象,而是创建一个对我当前使用的同一个对象的新引用。你知道吗</p>
<p>因此,如果我改变一个对象的值,它也会改变另一个对象的值——尽管我可能应该有两个完全不同的对象。你知道吗</p>
<p>使用<code>copy.deepcopy()</code>方法修复了引用的问题,但我猜它的工作方式也应该有所不同。你知道吗</p>
<p>我的代码在这个特定的实现中是如何工作的?它是否有理由创建同一对象的浅层副本,即使代码可能应该创建它的新实例?你知道吗</p>
<p>这是一个稍微简化的代码段:</p>
<pre><code>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))
</code></pre>
<p>问题在于类<code>Matrix4</code>,方法<code>mulM()</code>,其中<code>matrixResult = Matrix4()</code>应该创建一个全新的<code>Matrix4()</code>实例(其中<code>Vec4()</code>的所有值都应该是<code>0</code>),而不是简单地复制<code>self</code>对象。<code>print</code>的输出显示如下:</p>
<pre><code>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
</code></pre>
<p>所以第二个矩阵不应该等于第一个矩阵。
但是,如果我创建一个普通的<code>Matrix4()</code>对象,而不是在上述代码片段的最后扩展<code>Matrix4()</code>的<code>ScaleMatrix()</code>对象,则不会出现问题。你知道吗</p>
<p>Python v.3.6.4版</p>