Python 就地矩阵乘法uu imatmul uuuu返回修改后的对象

Python 就地矩阵乘法uu imatmul uuuu返回修改后的对象,python,python-3.x,matrix,Python,Python 3.x,Matrix,课程非常简单: 类矩阵(对象): 定义初始值(自身,值): self.values=值 定义(自身、其他): 返回矩阵(矩阵乘法(自身值、其他值)) 定义(自身、其他): 返回矩阵(矩阵乘法(自身值、其他值)) 定义(自身、其他): 返回自我。\uuuu matmul\uuuuu(其他) @静力学方法 def倍增(mat1、mat2): 返回[[总和(mat1*mat2表示mat1,mat2在zip中(mat1行,mat2列)) 对于邮政编码中的mat2_col(*mat2)] 对于MAT1MA

课程非常简单:

类矩阵(对象):
定义初始值(自身,值):
self.values=值
定义(自身、其他):
返回矩阵(矩阵乘法(自身值、其他值))
定义(自身、其他):
返回矩阵(矩阵乘法(自身值、其他值))
定义(自身、其他):
返回自我。\uuuu matmul\uuuuu(其他)
@静力学方法
def倍增(mat1、mat2):
返回[[总和(mat1*mat2表示mat1,mat2在zip中(mat1行,mat2列))
对于邮政编码中的mat2_col(*mat2)]
对于MAT1MAT1中的行]
定义报告(自我):
返回f“”
由于某些原因,在使用
\uuu imatmul\uuu
dunder方法时,我无法使其变换初始矩阵-ID不同:

mat1=矩阵([[11,12],[13,14]]
原始id\U mat1=id(mat1)
打印(f'mat1:{mat1},id:{orig_id_mat1}')
mat2=矩阵([[1,2],[3,4]]
原始id\U mat2=id(mat2)
打印(f'mat2:{mat2},id:{orig_id_mat2}')
mat1@=mat2
modif_id_mat1=id(mat1)
打印(f'mat1:{mat1},id:{modif_id_mat1}')
输出:

mat1: <Matrix values="[[11, 12], [13, 14]]">, id: 24458192
mat2: <Matrix values="[[1, 2], [3, 4]]">, id: 24458384
mat1: <Matrix values="[[47, 70], [55, 82]]">, id: 24458608
mat1:,id:24458192
mat2:,id:24458384
mat1:,id:24458608

\uuuu imatmul\uuuu
的实现中应该更改什么?

您的
\uuuu imatmul\uuuu
实现只是
\uu matmul\uuuu>的别名。它没有在适当的位置执行任何操作,因为您没有对其进行编码

首先,您应该了解操作符的就地版本的作用。表达式
a@=b
通常(但并非总是)等同于
a=type(a)。\uu imatmul\uuuu(a,b)
。这只是另一个函数调用。这样,您就可以对不可变对象执行“就地”操作,创建新结果但保留名称

您对
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
的调用就是这样做的:它创建并返回一个新对象,您可以用它替换矩阵

在适当的位置执行操作的一个简单方法是

def __imatmul__(self, other):
    self.values = self.multiply(self.values, other.values)
    return self
您还可以根据
\uuu imatmul\uuu
定义
\uuu matmul\uuu
,以简化维护:

def __matmul__(self, other):
    new = type(self)(self.values)
    return type(new).__imatmul__(new, other)
最后,您可能需要修复
的实现:

def __rmatmul__(self, other):
    return type(self).__matmul__(other, self)

嗯,是的。您的
\uuu imatmul\uuu
不会修改对象。里面没有什么东西能做到这一点。你希望Python为你做修改吗?你的
\uormamul\uumul
也被破坏了-它的行为就像
self
是LHS。
return other@self
仍然是一个破坏的
\uormamul\uumul
-如果
实际调用它,它将以无限递归结束。正确的做法是完全删除
\uu rmatmul\uu
,除非您确实希望支持混合类型
@
@user2357112supportsMonica。抢手货我是想偷懒<代码>\uuu rmatmul\uuu
在处理子类型时非常有用(尽管在父类型上并不真正需要它)。我已经修复了实现以避免无限递归。