检查包含的对象是否已更改

时间:2019-01-29 17:34:58

标签: python

我正在使用一个类来创建模块,该类充当另一个已创建类的列表的容器。容器类是否有办法判断包含的对象是否已更改?

这里是一个例子:

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属性是否已更改?

2 个答案:

答案 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)