Minor annoyances with properties

eb303 eric.brunel.pragmadev at gmail.com
Fri May 28 05:36:39 EDT 2010


On May 27, 8:56 pm, Francesco Bochicchio <bieff... at gmail.com> wrote:
> On 27 Mag, 14:37, eb303 <eric.brunel.pragma... at 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 -



More information about the Python-list mailing list