<div dir="ltr"><div>Ciao a tutti,</div><div><br></div><div>Vorrei definire una property in una gerarchia che si comporta diversamente in maniera polimorfica in funzione del tipo dell'oggetto su cui e' invocata. Mi vengono in mente 3 modi per farlo:</div>
<div>1) trattare la property con getter/setter alla Java e fare l'override solo dei comportamenti che cambiano => non pythonico, per cui direi proprio da evitare (ma ha i suoi vantaggi, vedi sotto)</div><div>2) usare il costrutto property => old style, richiede per forza di essere ridefinito nelle classi derivate, verboso</div>
<div>3) usare il decoratore @property => new style, analogo al precedente, comunque richiede di ridefinire la property nelle classi derivate che ne vogliono cambiare il comportamento</div><div><br></div><div>Ho messo alcuni esempi qua sotto. L'opzione #1 e' orrida, ma e' anche quella che richiede meno copia e incolla. L'opzione 3 e' credo quella che un pythonista si aspetterebbe, ma ha lo svantaggio di richiedere copia e incolla e ridefinire comportamenti che sono gia' definiti sulla superclasse.</div>
<div><br></div><div>Ci sono altri modi? Oppure fondamentalmente ho sviscerato le possibilita'?</div><div><br></div><div>Grazie e ciao</div><div>Giuliano</div><div><br></div><div><br></div><div>******* Codice *******</div>
<div>asdrubale:property giuliano.bossi$ cat java-style.py</div><div>class Dad(object):</div><div> def get_value(self):</div><div> return self._value</div><div><br></div><div> def set_value(self, value):</div>
<div> self._value = value</div><div><br></div><div> def __str__(self):</div><div> return "value={}".format(self._value)</div><div><br></div><div><br></div><div>class Son(Dad):</div><div> def set_value(self, value):</div>
<div> super(Son, self).set_value(value*2)</div><div><br></div><div><br></div><div>def func(arg):</div><div> arg.set_value(15)</div><div> print(arg)</div><div><br></div><div><br></div><div>func(Dad())</div><div>
func(Son())</div><div>asdrubale:property giuliano.bossi$ python java-style.py</div><div>value=15</div><div>value=30</div><div>asdrubale:property giuliano.bossi$ cat old-property.py</div><div>class Dad(object):</div><div> def get_value(self):</div>
<div> return self._value</div><div><br></div><div> def set_value(self, value):</div><div> self._value = value</div><div><br></div><div> value = property(get_value, set_value)</div><div><br></div><div> def __str__(self):</div>
<div> return "value={}".format(self._value)</div><div><br></div><div><br></div><div>class Son(Dad):</div><div> def set_value(self, value):</div><div> super(Son, self).set_value(value*2)</div><div>
<br></div><div> def get_value(self):</div><div> return super(Son, self).get_value()</div><div><br></div><div> # needed, not polymorphic</div><div> value = property(get_value, set_value)</div><div><br></div>
<div>def func(arg):</div><div> arg.value = 15</div><div> print(arg)</div><div><br></div><div><br></div><div>func(Dad())</div><div>func(Son())</div><div>asdrubale:property giuliano.bossi$ python old-property.py</div>
<div>value=15</div><div>value=30</div><div>asdrubale:property giuliano.bossi$ cat new-property.py</div><div>class Dad(object):</div><div> @property</div><div> def value(self):</div><div> return self._value</div>
<div><br></div><div> @value.setter</div><div> def value(self, value):</div><div> self._value = value</div><div><br></div><div> def __str__(self):</div><div> return "value={}".format(self._value)</div>
<div><br></div><div><br></div><div>class Son(Dad):</div><div> @property</div><div> def value(self):</div><div> return Dad.value.fget(self)</div><div><br></div><div> @value.setter</div><div> def value(self, value):</div>
<div> Dad.value.fset(self, value*2)</div><div><br></div><div><br></div><div>def func(arg):</div><div> arg.value = 15</div><div> print(arg)</div><div><br></div><div><br></div><div>func(Dad())</div><div>func(Son())</div>
<div>asdrubale:property giuliano.bossi$ python new-property.py</div><div>value=15</div><div>value=30</div><div>asdrubale:property giuliano.bossi$ python --version</div><div>Python 2.7.5</div><div><br></div>-- <br>Piergiuliano Bossi<br>
Blog: <a href="http://thinkingbox.wordpress.com/" target="_blank">http://thinkingbox.wordpress.com/</a><br>Twitter: <a href="http://twitter.com/thinkingbox" target="_blank">http://twitter.com/thinkingbox</a> (English)<br>
Twitter: <a href="http://twitter.com/scatolapensante" target="_blank">http://twitter.com/scatolapensante</a> (Italiano)<br><div>Google+: <a href="https://plus.google.com/u/0/108187981162465525118" target="_blank">https://plus.google.com/u/0/108187981162465525118</a></div>
</div>