From: eb303 on 28 May 2010 05:31 On May 27, 3:24 pm, Christian Heimes <li...(a)cheimes.de> wrote: > > Do I miss something? > > Is this the way to do it, or is there a better one? > > A better way was introduced in Python 2.6. Seehttp://docs.python.org/library/functions.html?highlight=property#prop... > I have a Python only version around if you are still using Python 2.5. > > Christian Mmmm, I might still miss something. OK, I can replace my initial property using @property and @p.setter, but it doesn't seem to work in subclasses: class A(object): @property def p(self): return self._p @p.setter def _set_p(self, p): self._p = p class B(A): @p.setter def _set_p(self, p): results in: Traceback (most recent call last): File "toto.py", line 8, in <module> class B(A): File "toto.py", line 9, in B @p.setter NameError: name 'p' is not defined
From: eb303 on 28 May 2010 05:36 On May 27, 8:56 pm, Francesco Bochicchio <bieff...(a)gmail.com> wrote: > On 27 Mag, 14:37, eb303 <eric.brunel.pragma...(a)gmail.com> wrote: > > > > > Hello all, > > > I've been using Python properties quite a lot lately and I've found a > > few things that are a bit annoying about them in some cases. I > > wondered if I missed something or if anybody else has this kind of > > problems too, and if there are better solutions than the ones I'm > > using ATM. > > > The first annoyance is when I want to specialize a property in a > > subclass. This happens quite often actually, and it is even sometimes > > the reason why a plain attribute is turned into a property: a subclass > > needs to do more things than the superclass when the property is > > updated for example. So, of course, my first try was: > > > class A(object): > > def __init__(self): > > self._p = None > > def _get_p(self): > > return self._p > > def _set_p(self, p): > > self._p = p > > p = property(_get_p, _set_p) > > class B(A): > > def _set_p(self, p): > > ## Additional things here > > super(B, self)._set_p(p) > > > And of course, it doesn't work: the property has been bound to > > A._set_p in A, so any new definition of _set_p in any subclass does > > not replace the set method for the property. So I always have to add a > > line: > > p = property(A._get_p, _set_p) > > in the subclass too. This is a bit awkward to me, since I have to > > specify the superclass's name (super( ) can't be used, since it should > > take B as an argument, and B isn't defined yet ). Do I miss something? > > Is this the way to do it, or is there a better one? > > Don't know if is better, but you could add a level of indirection to > solve it > > class A(object): > def __init__(self): > self._p = None > def _get_p(self): > return self._p > def _set_p(self, p): > self._p = p > def _virtual_get_p (self): _get_p(self) > def _virtual_set_p (self,v): _set_p(self, v) > p = property(_virtual_get_p, _virtual_set_p) > > At this point, the subclasses of A can reimplement _get_p and _set_p > as they like (I think) > > Ciao > ----- > FB Well, I've thought about that too and it should work, but that makes 2 function calls instead of one for every property access I'd really like to avoid that. By the way, I think your 'virtual' methods should be written as: def _virtual_get_p (self): return self._get_p() def _virtual_set_p (self,v): self._set_p(v) Thanks anyway. - Eric -
From: eb303 on 28 May 2010 05:46 On May 27, 3:14 pm, Neil Cerutti <ne...(a)norwich.edu> wrote: > On 2010-05-27, eb303 <eric.brunel.pragma...(a)gmail.com> wrote: > > > I've been using Python properties quite a lot lately and I've > > found a few things that are a bit annoying about them in some > > cases. I wondered if I missed something or if anybody else has > > this kind of problems too, and if there are better solutions > > than the ones I'm using ATM. > > The first annoyance is when I want to specialize a property in a > > subclass. > > See: > > URI:http://infinitesque.net/articles/2005/enhancing%20Python%27s%20proper.... > > -- > Neil Cerutti > *** You found a dead moose-rat. You sell the hide for $200. *** Thanks for the suggestion, but it looks a bit heavy Performing the name lookup on the specialized object each time the property is accessed seems a bit overkill. I'd really just like a simple way to tell in the subclass: now, the setter methof for property p is this one, only that Thanks again anyway. - Eric -
From: Christian Heimes on 28 May 2010 05:50 Am 28.05.2010 11:31, schrieb eb303: > On May 27, 3:24 pm, Christian Heimes <li...(a)cheimes.de> wrote: >>> Do I miss something? >>> Is this the way to do it, or is there a better one? >> >> A better way was introduced in Python 2.6. Seehttp://docs.python.org/library/functions.html?highlight=property#prop... >> I have a Python only version around if you are still using Python 2.5. >> >> Christian > > Mmmm, I might still miss something. OK, I can replace my initial > property using @property and @p.setter, but it doesn't seem to work in > subclasses: > > class A(object): > @property > def p(self): > return self._p > @p.setter > def _set_p(self, p): > self._p = p > class B(A): > @p.setter > def _set_p(self, p): > � > > results in: > > Traceback (most recent call last): > File "toto.py", line 8, in <module> > class B(A): > File "toto.py", line 9, in B > @p.setter > NameError: name 'p' is not defined It doesn't work because "p" is not in the scope of B's body while B is created. You have to write class B(A): # access the "p" property from class A @A.p.setter def p(self, p): pass # once p is in the class body scope, you must not use A.p again @p.deleter def p(self): pass Christian
From: eb303 on 28 May 2010 11:01
On May 28, 11:50 am, Christian Heimes <li...(a)cheimes.de> wrote: > Am 28.05.2010 11:31, schrieb eb303: > > > > > On May 27, 3:24 pm, Christian Heimes <li...(a)cheimes.de> wrote: > >>> Do I miss something? > >>> Is this the way to do it, or is there a better one? > > >> A better way was introduced in Python 2.6. Seehttp://docs.python.org/library/functions.html?highlight=property#prop... > >> I have a Python only version around if you are still using Python 2.5. > > >> Christian > > > Mmmm, I might still miss something. OK, I can replace my initial > > property using @property and @p.setter, but it doesn't seem to work in > > subclasses: > > > class A(object): > > @property > > def p(self): > > return self._p > > @p.setter > > def _set_p(self, p): > > self._p = p > > class B(A): > > @p.setter > > def _set_p(self, p): > > > > > results in: > > > Traceback (most recent call last): > > File "toto.py", line 8, in <module> > > class B(A): > > File "toto.py", line 9, in B > > @p.setter > > NameError: name 'p' is not defined > > It doesn't work because "p" is not in the scope of B's body while B is > created. You have to write > > class B(A): > # access the "p" property from class A > @A.p.setter > def p(self, p): > pass > > # once p is in the class body scope, you must not use A.p again > @p.deleter > def p(self): > pass > > Christian Well, I still have to explicitely specify the superclass's name then, so IMHO it's not a big improvement over repeating: p = property(A._get_p, _set_p) Thanks anyway - Eric - |