【问题标题】:Updating another class variable when a class variable is updated更新类变量时更新另一个类变量
【发布时间】:2019-05-02 21:17:22
【问题描述】:

我正在尝试创建一个存储原始输入的矩阵类,然后从原始输入创建另外 2 个变量,称为行和列,这意味着我可以通过执行类似矩阵([ [1, 2], [3, 4]]).rows[0] 得到 [1, 2] 或 matrix([[1, 2], [3, 4]]).columns[0] 得到 [ 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.columns 给了我

[[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?

【问题讨论】:

  • 我不明白这有什么目的。您已经覆盖了描述原始对象的属性;对象应该如何响应?您显然会出现不匹配的情况。您是否在 numpy 中寻找类似 @​​987654325@ 的内容?
  • 就是这样,我希望这些属性能够相互影响,而不仅仅是在初始化时只是行和列的副本。至于重塑,我不使用 numpy,所以我不知道那是什么。
  • 我希望它回应的是,每当我更新 matrix.columns[columnNumber] = a list 时,我希望它也更新 matrix.values,反之亦然

标签: python class variable-assignment


【解决方案1】:

你所问的并不容易。你想:

  • 在类中定义一些看起来像属性的东西
  • 但您不希望该属性保留任何值。
  • 显示另一个属性的转换
  • 能够检索或设置该转换的一部分

这样做的方法是创建一个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])

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-14
    相关资源
    最近更新 更多