【问题标题】:Wanting to update a list attribute in a class without having to call an update function for every change想要更新类中的列表属性,而不必为每次更改调用更新函数
【发布时间】:2021-06-16 01:15:13
【问题描述】:

这就是我正在使用的:

class Vector:
    def __init__(self):
        self.x = 0
        self.y = 0
        self.z = 0
        self.w = 0
        self.data = [
            [self.x],
            [self.y],
            [self.z],
            [self.w]
        ]

是否可以在其他属性更改时更新self.data? 我知道我可以为它写一个更新函数,比如:

def update(self):
        self.data = [
            [self.x],
            [self.y],
            [self.z],
            [self.w]
            ]

但我宁愿不调用v.update() 60 次/秒。

我也知道我不能使用其他属性并通过执行 v.data[0] = 5 来更新列表索引,但为了便于阅读,最好执行 v.x = 5(v 是 Vector 的一个实例)。

现在我只是咬v.data[0] = 5子弹...

编辑:数据是矩阵乘法的列表。

【问题讨论】:

  • 为什么不把self.data 变成@property?为什么是列表列表?
  • 不,不是整数
  • @jonrsharpe:将data 实现为属性将阻止更新反映在向量的状态中。 (不过,列表的列表很奇怪。)
  • 我可能要么完全消除data(并且可能使Vector成为序列类型),或者使xyzw属性得到支持data.
  • @user2357112supportsMonica 你的意思是例如如果v.data[0] = 5 发生在课外?是的,没错,可变属性可能不是一个好主意,因为它会导致令人惊讶的行为。

标签: python list class attributes


【解决方案1】:

您可以为具有自定义更新方法的xyzw 创建自己的对象。这样,当这些属性更新时,更改将通过 data 中的引用反映出来:

class Component:
   def __init__(self, val = 0, name='x'):
      self.val, self.name = val, name
   def update(self, new_val):
      self.val = new_val
   def __repr__(self):
      return f'{self.name}({self.val})'

class Vector:
   def __init__(self):
      self.x = Component(name='x')
      self.y = Component(name='y')
      self.z = Component(name='z')
      self.w = Component(name='w')
      self.data = [
        [self.x],
        [self.y],
        [self.z],
        [self.w]
      ]

v = Vector()
print('before update: ', v.data)
v.x.update(100)
v.y.update(200)
v.z.update(300)
v.w.update(400)
print('after update: ', v.data)

输出:

before update:  [[x(0)], [y(0)], [z(0)], [w(0)]]
after update:  [[x(100)], [y(200)], [z(300)], [w(400)]]

【讨论】:

    【解决方案2】:

    您可以使用单个位置来存储数据,并使 x、y、z、w 人员在各自的索引处读取和写入 self.data:

    class Vector:
        
        def dataProperty(i):
            def getter(obj): return obj.data[i][0]
            def setter(obj,value): obj.data[i][0] = value
            return property(getter,setter)
    
        x,y,z,w = map(dataProperty,range(4))
        
        def __init__(self):
            self.data = [[0] for _ in range(4)]
    

    输出:

    v = Vector()
    v.x = 123
    v.z = 456
    
    print(v.data) # [[123], [0], [456], [0]]
    
    v.data[0][0] += 876
    
    print(v.x) # 999
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多