代码之家  ›  专栏  ›  技术社区  ›  James Peter McConnell

如何访问setitem定义语法和示例?

  •  -1
  • James Peter McConnell  · 技术社区  · 6 年前

    我有一个矩阵类类似于 here :

    class Matrix(object):
    
        def __init__(self, m, n, init=True):
            if init:
                self.rows = [[0]*n for x in range(m)]
            else:
                self.rows = []
            self.m = m
            self.n = n
    
        def __setitem__(self, idx, item):
            self.rows[idx] = item
            print("HERE")
    
        ...
    

    my_mat = 0000                    my_mat = 0000
             0000           ->                0200
             0000                             0000
             0000                             0000
    

    在我的 main()

    from matrix import Matrix
    
    def main():
    
        # Create matrix
        my_mat = Matrix(4,3)
    
        # Set element
        my_mat[1][1] = 2
        print(my_mat)
    
    
    if __name__ == "__main__":
    
        main()
    

    这个 __setitem__ 定义需要3个参数(其中一个是 self ,自动提供)。所以, id item 是必要的。我尝试了许多不同的组合来设置矩阵的元素。当我尝试设置元素(上面)时,“HERE”没有打印出来。似乎我没有访问 __设置项__

    如何使用 __设置项__

    我尝试过类似的变化:

    my_mat(1,1) = 2
    my_mat(1,1,2)
    my_mat([1,1],2)
    

    .... 但都失败了。

    2 回复  |  直到 6 年前
        1
  •  0
  •   martineau    6 年前

    这个 __setitem__() 中的方法 Matrix __getitem__() 方法)。

    所以,调用 __设置项 方法需要如下内容:首先检索整行,更改其中的单个元素,然后将整行存储回同一行索引处的矩阵中:

    def main():
    
        # Create matrix
        my_mat = Matrix(4,3)
    
        # Set single element, logically equivalent to my_mat[1][1] = 2
        row = my_mat[1]  # Uses Matrix.__getitem__()
        row[1] = 2       # Change single element of row.
        my_mat[1] = row  # Uses Matrix.__setitem__() to replace row
        print(my_mat)
    

    如文中所述,配方确实 提供一种只需一行代码就可以完成这一切的方法。如果要经常这样做,您需要修改 矩阵

    如果你不知道怎么做,找一个不同的配方来支持它(或者在这里问另一个问题)。我想)。

    临别赠言:我建议你考虑一下 numpy 附加模块(它不是Python内置的)。它还有许多其他有用的特性,而且速度非常快。

    小更新

    为了好玩,我想出了一种非常老套且不可读的方法,可以在一行代码中完成它:

        # Logically equivalent to my_mat[1][1] = 2
        my_mat[1] = (lambda r, i, v: (r.__setitem__(i, v), r)[1])(my_mat[1], 1, 2)
    

    r , i ,和 v :

    1. :要修改的行
    2. :项的新值

    此函数调用行 __设置项

    这个 矩阵 “类” __设置项

    (我不建议您这样做……但希望这会让您了解类的新方法有哪些o,因为这需要做类似的事情。)

        2
  •  0
  •   natonomo    6 年前

    我想在这种情况下你应该定义 __getitem__ 并让它返回正确的行:

    def __getitem__(self, item):
        if isinstance(item, int):
            return self.rows[item]
        return super().__getitem__(item)
    

    或者,定义一个更复杂的 __setitem__ here

    另外,与您的问题无关,请注意 else rows 作为一个一维的列表而不是二维的,不确定你是否打算这么做。