【问题标题】:How is __setitem__() working with 4 arguments?__setitem__() 如何处理 4 个参数?
【发布时间】: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


    【解决方案1】:

    不起作用。它根本没有被调用。

    当您执行m_obj[rindex][cindex] = val 时,Python 会调用__getitem__ 来获取m_obj[rindex] 的值。然后它将调用该值的__setitem__ 方法。您可以通过在您的方法中添加打印来证明这一点。

    【讨论】:

    • 谢谢!所以你建议不要为我的班级定义__setitem__()
    猜你喜欢
    • 1970-01-01
    • 2023-03-27
    • 2021-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多