好,其他人已指出,這個問題歸結爲一個事實,即你'正在處理imutable objects。意識到這一點後,您應該使用可變類型,或使用回調來管理更新。阿德里亞諾阿布蘭特什使用了可變類型的替代的例子,但如果這不是你要找的內容,這裏有潛在的回調系統的一個例子:
# bad habit to be using the old style class definition (i.e. `class Foo:`)
# the `@property` decorator wont work if you use the old style
class Sync(object):
def __init__(self, name, value, *dependants):
"""Sync the attribute `name` on all `dependants` when `self.value` is updated"""
self._name = name
self._value = value
self._updating = False
self._dependants = list(dependants)
self._update_dependants()
@property
def value(self):
return self._value
@value.setter
def value(self, x):
if x != self._value:
self._value = x
self._update_dependants()
def _update_dependants(self):
self._updating = True
for d in self._dependants:
if getattr(d, self._name) != self.value:
if isinstance(d, Sync):
if not d._updating:
setattr(d, self._name, self.value)
else:
setattr(d, self._name, self.value)
self._updating = False
def add_dependant(self, other):
self._dependants.append(other)
self._update_dependants()
def del_dependnant(self, other):
self._dependants.remove(other)
def __repr__(self):
return "Sync('"+self._name+"': "+repr(self.value)+")"
def __eq__(self, other):
if isinstance(other, Sync):
return self.value == other.value
else:
return self.value == other
def __ne__(self, other):
return not self.__eq__(other)
s1 = Sync('value', 2)
s2 = Sync('value', 1)
print('setup the Sync objects:')
print('>>> ' + repr(s1) + (' == ' if s1 == s2 else ' != ') + repr(s2))
s1.add_dependant(s2)
s2.add_dependant(s1)
print('add sync objects as dependants of each other:')
print('>>> ' + repr(s1) + (' == ' if s1 == s2 else ' != ') + repr(s2))
s1.value += 1
print('check that value changes transfer from one to the other:')
print('>>> ' + repr(s1) + (' == ' if s1 == s2 else ' != ') + repr(s2))
如果這還不能滿足你,我就看看Traitlets。這是來自Ipython的一個包,它是Project Jupyter的一部分,它強制執行類型檢查,簡化回調系統並簡化應用程序配置。我一直在爲該項目做出貢獻,因此如果您對Traitlets有任何疑問,請隨時在這裏問我或在Gitter上發帖,開發團隊將回答他們。
不,你不能用不可變對象來做到這一點。 – jonrsharpe
你可以用間接方式來做,但是你不應該這樣做。你在這裏試圖解決什麼問題? –
你必須對y使用setter函數,所以你不能說y.l + = 1,你必須說y.set(x,1)。然後y的setter應該照顧更新x和y。 Foo: def set(var,val): y.l + = val var.n = val –