我正在使用一个类来创建模块,该类充当另一个已创建类的列表的容器。容器类是否有办法判断包含的对象是否已更改?
这里是一个例子:
class Part:
def __init__(self, size):
self.part_size = size
class Assembly:
def __init__(self, *parts):
self.parts = list(parts) # `parts` are all Part() objects
self.update()
def update(self):
self.assy_size = 0
for each in self.parts:
self.assy_size += each.part_size
def __getitem__(self, key):
return self.parts[key]
如果我尝试更改Part
中的任何Assembly
属性,就会得到以下结果:
>>>x = Part(1)
>>>y = Part(1)
>>>z = Part(1)
>>>u = Assembly(x, y, z)
>>>u.assy_size
3
>>>u[0].part_size = 4
>>>u.assy_size
3
我知道我可以创建其他方法,如果我将update
对象替换,删除或添加到Part
中,则会调用Assembly
方法,但是有什么方法可以Assembly
是否收到通知,其中包含的Part
属性是否已更改?
答案 0 :(得分:3)
答案在您的问题中。使用属性。
class Part:
_size = 0
assembly = None
@property
def part_size(self):
return self._size
@part_size.setter
def part_size(self, value):
self._size = value
if self.assembly: # only notify if an Assembly is set
self.assembly.update()
def set_assembly(self, assembly):
self.assembly = assembly
def __init__(self, size):
self.part_size = size
class Assembly:
def __init__(self, *parts):
self.parts = list(parts) # `parts` are all Part() objects
for part in self.parts:
part.set_assembly(self) # reference to self needed to notify changes
self.update()
def update(self):
self.assy_size = 0
for each in self.parts:
self.assy_size += each.part_size
在Assembly
的此版本中,构造函数在Part
上为其自身设置了一个引用。这样,当part_size
更改时,它可以更新程序集。用它作为您问题中的示例。
>>>x = Part(1)
>>>y = Part(1)
>>>z = Part(1)
>>>u = Assembly(x, y, z)
>>>u.assy_size
3
>>>u[0].part_size = 4
>>>u.assy_size
6
答案 1 :(得分:0)
如果update
不是昂贵的操作(在您的示例中不是,但是实际上您有成千上万的零件),则可以使用属性来临时计算尺寸:
class Assembly:
def __init__(self, *parts):
self.parts = list(parts)
@property
def assy_size(self):
result = 0
for each in self.parts:
result += each.part_size
return result
可以用相同的方式访问:assembly.assy_size
。
计算也可以简化:
@property
def assy_size(self):
return sum(part.part_size for part in self.parts)