Le Wednesday 03 September 2008 15:57:50 mk, vous avez écrit : > I try to set two properties, "value" and "square" in the following code, > and arrange it in such way that setting one property also sets another > one and vice versa. But the code seems to get Python into infinite loop: > > >>> import math > >>> class Squared2(object): > > def __init__(self, val): > self._internalval=val > self.square=pow(self._internalval,2) > > def fgetvalue(self): > return self._internalval > > def fsetvalue(self, val): > self._internalval=val > self.square=pow(self._internalval,2) > > value = property(fgetvalue, fsetvalue) > > def fgetsquare(self): > return self.square > def fsetsquare(self,s): > self.square = s > self.value = math.sqrt(self.square) > > square = property(fgetsquare, fsetsquare) > > > >>> a=Squared2(5) > > Traceback (most recent call last): > File "<pyshell#11>", line 1, in <module> > a=Squared2(5) > File "<pyshell#10>", line 5, in __init__ > self.square=pow(self._internalval,2) > File "<pyshell#10>", line 19, in fsetsquare > self.square = s > File "<pyshell#10>", line 19, in fsetsquare > self.square = s > File "<pyshell#10>", line 19, in fsetsquare > self.square = s > File "<pyshell#10>", line 19, in fsetsquare > self.square = s > File "<pyshell#10>", line 19, in fsetsquare > self.square = s > File "<pyshell#10>", line 19, in fsetsquare > > ... > > Is there a way to achieve this goal of two mutually setting properties?
Your square property is not correctly defined, it recurselively call itself, it should be (I also avoided the extra lookup) : def fgetsquare(self): return self._square def fsetsquare(self,s): self._square = s self.value = math.sqrt(s) then the fsetvalue will be also be called recursively as it use the square property, you should also write it : def fsetvalue(self, val): self._internalval=val self._square=pow(val,2) *but*, if you want to add more logic in the setters, you could want to add two extra methods : def _setsquare(self, v) : # some extra logic here self._square = s def fsetsquare(self,s): self._setsquare(s) self._setvalue = math.sqrt(s) def _setvalue(self, val): # some extra logic here self._internalval=val def fsetvalue(self, val): self._setvalue(val) self._setsquare=pow(val,2) Note that if one property can really be computed from another, this kind of thing could be considered as bad design (except if the computation is heavy). -- _____________ Maric Michaud -- http://mail.python.org/mailman/listinfo/python-list