From: eb303 on
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
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
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
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
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 -