【发布时间】:2019-10-18 11:07:23
【问题描述】:
我正在编写一个 Matrix 类,其中 [] 运算符重载。
由于保存矩阵的self.matrix 是一个列表列表,因此按照惯例,__getitem__() 方法采用 2 个参数 self, index,返回一个可以进一步下标的列表(行)。
但是__setitem__() 呢?根据定义,它不应该只采用 3 个参数吗?我已经用 4 个参数进行了尝试,它以某种方式工作正常。
我知道可以传入一个元组参数来访问矩阵元素,但我想知道 为什么 这使用 4 个参数?这是未定义的行为吗?如果我写m_obj[rindex][cindex] = val,它可以完美运行!
如果我只做m_obj[rindex] = val,我会收到以下错误:
Traceback (most recent call last):
File "<pyshell#9>", line 1, in <module>
a[1] = 1
TypeError: __setitem__() missing 1 required positional argument: 'val'
但这确实是我想要的,除了缺少的位置参数是cindex 而不是val。
相反,如果我给__getitem__()添加一个额外的参数,代码就不起作用了:
def __getitem__(self, rindex, cindex):
return self.matrix[rindex][cindex]
我在获取和设置时都遇到了这个错误:
>>> a[1][1] = 1
Traceback (most recent call last):
File "<pyshell#21>", line 1, in <module>
a[1][1] = 1
TypeError: __getitem__() missing 1 required positional argument: 'cindex'
代码如下:
class DimensionError(BaseException):
pass
class Matrix:
def __init__(self, rows, cols):
self.rows = rows
self.cols = cols
self.matrix = [[] for i in range(self.rows)]
for i in range(self.rows):
self.matrix.app
for j in range(self.cols):
self.matrix[i].append(0)
def __str__(self):
matrep = ''
for i in self.matrix:
matrep += str(i) + '\n'
return matrep
def __getitem__(self, index):
return self.matrix[index]
def __setitem__(self, rindex, cindex, val):
self.matrix[rindex][cindex] = val
def __add__(self, secmat):
if self.rows != secmat.rows or self.cols != secmat.cols:
raise DimensionError('Incompatible Matrices for Addition')
newmat = Matrix(self.rows, self.cols)
for i in range(self.rows):
for j in range(self.cols):
newmat[i][j] = self[i][j] + secmat[i][j]
return newmat
def __sub__(self, secmat):
if self.rows != secmat.rows or self.cols != secmat.cols:
raise DimensionError('Incompatible Matrices for Subtraction')
newmat = Matrix(self.rows, self.cols)
for i in range(self.rows):
for j in range(self.cols):
newmat[i][j] = self[i][j] - secmat[i][j]
return newmat
def __matmul__(self, secmat):
if self.cols != secmat.rows:
raise DimensionError('Incomatible Matrices for Multiplication. Product is undefined')
newmat = Matrix(self.rows, secmat.cols)
for i in range(self.rows):
for j in range(secmat.cols):
for k in range(secmat.rows):
newmat[i][j] += (self[i][k] * self[k][j])
return newmat
def __mul__(self, secmat):
return self.__matmul__(secmat)
#Driver
a = Matrix(2, 2)
b = Matrix(2, 2)
print('Enter elements of first matrix:')
for i in range(a.rows):
for j in range(a.cols):
a[i][j] = int(input(f'Enter element [{i}{j}] >>>'))
print('Enter elements of second matrix:')
for i in range(b.rows):
for j in range(b.cols):
b[i][j] = int(input(f'Enter element [{i}{j}] >>>'))
print('Matrix a: ')
print(a)
print('Matrix b: ')
print(b)
print('Multiplication is:')
print(a @ b) # or a * b
我已经在没有 f-strings 和 @ 运算符的 Python 2.7 中尝试过它,它的工作原理是一样的。
有人能解释一下幕后发生了什么吗?
提前致谢!
【问题讨论】:
标签: python matrix operator-overloading