You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在类变量变更时调用指定函数?多变量场景简化方案咨询

批量绑定属性修改触发函数的简化方案

当需要给多个属性绑定修改触发逻辑时,重复编写@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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 21:58:18