如何在类变量变更时调用指定函数?多变量场景简化方案咨询
批量绑定属性修改触发函数的简化方案
当需要给多个属性绑定修改触发逻辑时,重复编写@property和setter确实冗余。你可以通过动态生成属性或元类两种方式批量处理这类需求,以下是两种实用实现:
方式一:动态生成属性(简单直观)
通过辅助函数批量为类添加带触发逻辑的属性,后续新增属性只需在对应列表中添加变量名即可:
class Event: def __init__(self, a, b, c): # 初始化私有变量 self._a = a self._b = b self._c = c def func1(self): print("Function 1 called") def func2(self): print("Function 2 called") # 辅助函数:给类添加绑定了触发函数的属性 def add_triggered_property(cls, attr_name, trigger_func): private_attr = f"_{attr_name}" # 定义getter def getter(self): return getattr(self, private_attr) # 定义带触发逻辑的setter def setter(self, value): setattr(self, private_attr, value) print(f"Variable {attr_name} changed!") getattr(self, trigger_func)() # 为类绑定property setattr(cls, attr_name, property(getter, setter)) # 批量绑定属性与触发函数 for attr in ['a', 'c']: add_triggered_property(Event, attr, 'func1') add_triggered_property(Event, 'b', 'func2') # 测试代码 obj = Event(1, 2, 3) obj.a = 15 obj.b = 10 obj.c = 5
方式二:元类实现(优雅易维护)
利用元类在类定义阶段自动生成属性,通过trigger_map直接声明属性组与触发函数的对应关系,可读性和扩展性更强:
class TriggerMeta(type): def __new__(cls, name, bases, attrs): # 提取类中定义的属性-触发函数映射 trigger_map = attrs.pop('trigger_map', {}) new_cls = super().__new__(cls, name, bases, attrs) # 遍历映射批量生成property for attr_names, func_name in trigger_map.items(): for attr in attr_names: private_attr = f"_{attr}" # 定义getter def getter(self, target_attr=private_attr): return getattr(self, target_attr) # 定义带触发逻辑的setter def setter(self, value, target_attr=private_attr, func=func_name): setattr(self, target_attr, value) print(f"Variable {attr} changed!") getattr(self, func)() # 绑定到类 setattr(new_cls, attr, property(getter, setter)) return new_cls class Event(metaclass=TriggerMeta): # 直接声明属性组与触发函数的对应关系 trigger_map = { ('a', 'c'): 'func1', ('b',): 'func2' } def __init__(self, a, b, c): self._a = a self._b = b self._c = c def func1(self): print("Function 1 called") def func2(self): print("Function 2 called") # 测试代码 obj = Event(1, 2, 3) obj.a = 15 obj.b = 10 obj.c = 5
内容的提问来源于stack exchange,提问作者user23638776
相关产品推荐
相关产品推荐

