更新类变量时更新另一个类变量

时间:2018-11-30 17:29:27

标签: python class variable-assignment

我正在尝试创建一个存储原始输入的矩阵类,然后从原始输入中再创建2个变量,称为行和列,这意味着我可以通过执行诸如matrix([ [1,2],[3,4]]。rows [0]得到[1,2]或矩阵([[1,2],[3,4]])。columns [0]得到[1,2] 1、3]。到目前为止,这很好用,但是如果我想将行或列重新分配给另一个值,例如:

A = matrix([[1, 2], [3, 4]])
print(A.columns[0])

这给了我

  

[1,2]

但是如果我要进一步执行此代码块以更新这样的列,

A.columns[0] = [5, 6]

然后再次打印出A,它将为我提供原始输入

print(A)
  

[[1、2],[3、4]]

但是打印a.columns [0]会给我更新的列

  

[5,6]

并整体打印a。列会给我

  

[[5,6],[2,4]]

我将如何编写A.columns [0]同时更新输入变量和列变量的代码? 这是我的原始代码:

class matrix:
    def __init__(self, values):
        self.values = values
        self.rows = [row for row in self.values]
        self.columns = [[row[i] for row in self.values] for i in    range(list(set([len(row) for row in self.values]))[0])]

    def __setattr__(self, name, value):
        if name not in ["rows", "columns"]:
            self.__dict__[name] = value
        elif hasattr(self, name):
            #This is the part of code I'm trying to use to attempt updating self.values and self.columns at once, but it isn't even printing so I didn't bother writing any code for it
            print name, value
        else:
            self.__dict__[name] = value

    def __setitem__(self, index, value):
        print index, value

    def __str__(self):
        return str(self.values)

a = matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
a.columns[1] = [4, 4, 4]
print(a)

仍然给予

  

[[1、2、3],[4、5、6],[7、8、9]]

当我希望它给我[[1、4、3],[4、4、6],[7、4、9]]时,但是更新列变量与self无关.values(它是原始输入变量),因为它就像有2个完全独立的变量一样。我如何将它们链接在一起,以便self.values的任何更改都更新为self.columns和self.rows,self.columns和self.rows的所有更改都更新self.values?

1 个答案:

答案 0 :(得分:0)

您要问的事情并不容易。您要:

  • 在类中定义类似于属性的内容
  • 但是您不希望该属性保留任何值。
  • 显示另一个属性的变换
  • 能够检索或设置该转换的一部分

要做的是创建一个property attribute,它会为您提供所需的内容,而不是在创建实例时复制值。然后,该属性属性可以覆盖该方法以模拟matrix中的索引。它可能看起来像:

class Matrix:

    def __init__(self, values):
        self.values = values
        self.rows = self.Row_view(self)
        self.columns = self.Columns_view(self)

    class Columns_view:

        def __init__(self, owner):
            self.owner = owner

        def __str__(self):
            return str(list(list(x) for x in zip(*self.owner.values)))

        def __getitem__(self, key):
            return [row[key] for row in self.owner.values]

        def __setitem__(self, key, new_values):
            for (row, new_row_value) in zip(self.owner.values, new_values):
                row[key] = new_row_value

    class Row_view:

        def __init__(self, owner):
            self.owner = owner

        def __str__(self):
            return str(self.owner.values)

        def __getitem__(self, key):
            return self.owner.values[key]

        def __setitem__(self, key, new_values):
            self.owner.values[key] = new_values

    def __str__(self):
        return str(self.values)

A = Matrix([[1, 2], [3, 4]])
print(A.columns[0])

A.columns[0] = [5, 6]
print(A)

print(A.columns[0])
print(A.columns)

a = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
a.columns[1] = [4, 4, 4]
print(a)

print(a.columns[:2])

可能还有其他方法可以做到这一点,但这可能是更简单的方法,除非您有其他要求。