python 利用描述器 批量修改分组的属性值

问题:class中的属性值init_height是一个变量,另一个属性值real_height是以init_height为参数的计算公式算出的值,现在有多个此类,该如何管理这些类的数据,现在要求上述的代码具备以下两个功能:1.初始化时,不进行分组,后面指定部分类进行分组。2.要求同组的init_height属性值都是一样的,且当我二次更改class中的init_height属性值时,同组的class的real_height属性值都要更新,且更新后的值也是一样的。3.同时要求计算的方法是可以修改的。

class MyClass:
    data = []
    groups = {}

    def __init__(self, init_height=None, calculate_real_height=None):
        self._init_height = init_height
        self.calculate_real_height = calculate_real_height
        self.real_height = None
        self.group = None
        MyClass.data.append(self)

    @property
    def init_height(self):
        return self._init_height

    @init_height.setter
    def init_height(self, value):
        if self.group is not None:
            self.update_group_init_height(value)
            self.update_real_height()
        self._init_height = value

    def update_group_init_height(self, value):
        group = self.group
        for obj in MyClass.groups[group]:
            obj._init_height = value

    def update_real_height(self):
        group = self.group
        init_height = self._init_height
        for obj in MyClass.groups[group]:
            obj.real_height = obj.calculate_real_height(init_height)

    @staticmethod
    def assign_group(obj, group):
        if group not in MyClass.groups:
            MyClass.groups[group] = []
        MyClass.groups[group].append(obj)
        obj.group = group

    @classmethod
    def update_all_real_height(cls):
        for obj in cls.data:
            if obj.group is not None:
                obj.update_real_height()


def create_class(init_height=None, calculate_real_height=None):
    return MyClass(init_height, calculate_real_height)


# 定义分组的init_height和计算real_height的方式
group1_calculate_real_height = lambda init_height: init_height * 2
group2_calculate_real_height = lambda init_height: init_height ** 2

# 创建类
obj1 = create_class(calculate_real_height=group1_calculate_real_height)
obj2 = create_class(calculate_real_height=group1_calculate_real_height)
obj3 = create_class(calculate_real_height=group2_calculate_real_height)
obj4 = create_class(calculate_real_height=group2_calculate_real_height)

# 指定部分类进行分组
MyClass.assign_group(obj1, "Group1")
MyClass.assign_group(obj2, "Group1")
MyClass.assign_group(obj3, "Group2")
MyClass.assign_group(obj4, "Group2")

# 定义各组的初始 init_height 值
group1_init_height = 5
group2_init_height = 10

# 初始化各组的 init_height 属性值,并更新 real_height
for obj in MyClass.groups["Group1"]:
    obj.init_height = group1_init_height
for obj in MyClass.groups["Group2"]:
    obj.init_height = group2_init_height

# 获取所有类的数据
all_data = MyClass.data
for obj in all_data:
    print(f"Group: {obj.group}, Init Height: {obj.init_height}, Real Height: {obj.real_height}")

# 修改同组的 init_height 属性值,并更新同组的 real_height
obj1.init_height = 7

# 更新所有类的 real_height
MyClass.update_all_real_height()

# 获取所有类的数据
all_data = MyClass.data
for obj in all_data:
    print(f"Group: {obj.group}, Init Height: {obj.init_height}, Real Height: {obj.real_height}")