Python中减等运算符为何不调用属性setter方法?
问题原因
你遇到的情况是因为列表是可变对象:
test.offset[1] -= 1并没有给test.offset重新赋值,只是直接修改了self._offset指向的列表内部元素。- 只有当执行
test.offset = 新对象这类重新赋值操作时,才会触发offset的 setter 方法。
解决方案
下面提供几种可行的解决思路:
方案1:手动触发setter(简单直接)
每次修改列表元素后,手动将列表重新赋值给 offset,强制触发setter:
test = Test() temp = test.offset temp[1] -= 1 test.offset = temp # 这里会调用setter,打印"set"
方案2:改用不可变类型(如元组)
将offset改为元组,因为元组不可变,修改时必须重新创建新元组并赋值,自然触发setter:
class Test(): def __init__(self): self.offset = (0, 0) @property def offset(self): return self._offset @offset.setter def offset(self, offset): print("set") self._offset = offset test = Test() test.offset = (test.offset[0], test.offset[1] - 1) # 触发setter
方案3:自定义可观察的容器类(优雅适配原有用法)
封装一个自定义列表类,在修改元素时自动触发回调,间接调用setter,这样可以保留类似列表的操作方式:
class ObservableList: def __init__(self, data, update_callback): self._data = list(data) self._update_callback = update_callback def __getitem__(self, idx): return self._data[idx] def __setitem__(self, idx, value): self._data[idx] = value # 修改元素时触发回调,通知外部更新 self._update_callback(list(self._data)) def __repr__(self): return repr(self._data) class Test(): def __init__(self): self.offset = [0, 0] @property def offset(self): return self._offset @offset.setter def offset(self, offset): print("set") # 创建可观察列表,修改元素时自动调用setter更新 self._offset = ObservableList(offset, lambda new_data: setattr(self, 'offset', new_data)) test = Test() test.offset[1] -= 1 # 自动触发setter,打印"set"
内容的提问来源于stack exchange,提问作者Anatole Sot
相关产品推荐
相关产品推荐

