如何为类的setter属性添加装饰器?
如何为类的setter属性添加装饰器?
嘿,我来帮你搞定这个给setter加装饰器的问题!你已经有了Tracker和Aggregator这两个类,现在想给Tracker里value属性的setter加上自定义装饰器对吧?其实步骤很清晰,我给你拆解成两种常见场景来说明。
场景一:在类定义时直接给setter加装饰器
首先咱们得先写一个自定义装饰器,比如我写个做值验证的装饰器(你可以根据自己的需求改逻辑,比如加日志、做权限校验都行):
def validate_value(func): def wrapper(self, value): # 这里放你需要的自定义逻辑,比如验证值的类型 print(f"正在处理值的设置:{value}") if not isinstance(value, (int, float)): raise ValueError("值必须是整数或浮点数哦!") # 调用原本的setter方法 return func(self, value) return wrapper
接下来,把这个装饰器加到Tracker的setter上就行啦!注意装饰器的顺序:咱们自己的@validate_value要放在@value.setter的下面,因为Python的装饰器是从下往上执行的,先让自定义装饰器包装setter方法,再把包装后的方法注册成value属性的setter。
修改后的Tracker类是这样的:
class Tracker(): def __init__(self): self._value = None @property def value(self): return self._value @value.setter @validate_value # 这里加上咱们的自定义装饰器 def value(self, value): self._value = value
你可以测试一下效果:
tracker = Tracker() tracker.value = 15 # 会打印"正在处理值的设置:15",正常设置值 print(tracker.value) # 输出15 try: tracker.value = "这不是数字" # 触发验证逻辑 except ValueError as e: print(e) # 输出"值必须是整数或浮点数哦!"
场景二:在Aggregator中动态给传入的Tracker实例加装饰器
如果你不想修改Tracker类的原代码,而是想在Aggregator接收trackers的时候,动态给这些实例的setter加上装饰器,也完全没问题。咱们可以通过property的fget(获取getter方法)和fset(获取setter方法)属性,把原setter包装后重新赋值:
class Aggregator(): def __init__(self, trackers): self.trackers = trackers # 遍历每个传入的tracker,给它们的value setter加装饰器 for tracker in trackers: # 拿到原有的getter和setter方法 original_getter = tracker.value.fget original_setter = tracker.value.fset # 用自定义装饰器包装原setter wrapped_setter = validate_value(original_setter) # 重新设置value属性的property tracker.value = property(original_getter, wrapped_setter)
测试一下这个动态添加的效果:
tracker1 = Tracker() tracker2 = Tracker() aggregator = Aggregator([tracker1, tracker2]) tracker1.value = 30 print(tracker1.value) # 输出30,同时打印"正在处理值的设置:30" try: tracker2.value = "无效值" except ValueError as e: print(e) # 输出"值必须是整数或浮点数哦!"
内容来源于stack exchange
相关产品推荐
相关产品推荐

