Я пишу класс 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
Я пробовал это в Python 2.7 без f-строк и оператора @
, и он работает точно так же.
Может кто-нибудь объяснить, что происходит под капотом?
Заранее спасибо!