@x.setter property implementation

Floris Bruynooghe floris.bruynooghe at gmail.com
Fri Apr 11 12:19:22 CEST 2008


On Apr 11, 10:16 am, Floris Bruynooghe <floris.bruynoo... at gmail.com>
wrote:
> On Apr 10, 5:09 pm, Arnaud Delobelle <arno... at googlemail.com> wrote:
>
>
>
> > On Apr 10, 3:37 pm, Floris Bruynooghe <floris.bruynoo... at gmail.com>
> > wrote:
>
> > > On Apr 7, 2:19 pm, "Andrii V. Mishkovskyi" <misho... at gmail.com> wrote:
>
> > > > 2008/4/7, Floris Bruynooghe <floris.bruynoo... at gmail.com>:
>
> > > > >  Have been grepping all over the place and failed to find it.  I found
> > > > >  the test module for them, but that doesn't get me very far...
>
> > > > I think you should take a look at 'descrobject.c' file in 'Objects' directory.
>
> > > Thanks, I found it!  So after some looking around here was my
> > > implementation:
>
> > > class myproperty(property):
> > >     def setter(self, func):
> > >         self.fset = func
>
> > > But that doesn't work since fset is a read only attribute (and all of
> > > this is implemented in C).
>
> > > So I've settled with the (nearly) original proposal from Guido on
> > > python-dev:
>
> > > def propset(prop):
> > >     assert isinstance(prop, property)
> > >     @functools.wraps
> > >     def helper(func):
> > >         return property(prop.fget, func, prop.fdel, prop.__doc__)
> > >     return helper
>
> > > The downside of this is that upgrade from 2.5 to 2.6 will require code
> > > changes, I was trying to minimise those to just removing an import
> > > statement.
>
> > > Regards
> > > Floris
>
> > Here's an implementation of prop.setter in pure python < 2.6, but
> > using sys._getframe, and the only test performed is the one below :)
>
> > import sys
>
> > def find_key(mapping, searchval):
> >     for key, val in mapping.iteritems():
> >         if val == searchval:
> >             return key
>
> > _property = property
>
> > class property(property):
> >     def setter(self, fset):
> >         cls_ns = sys._getframe(1).f_locals
> >         propname = find_key(cls_ns, self)
> >         # if not propname: there's a problem!
> >         cls_ns[propname] = property(self.fget, fset,
> >                                     self.fdel, self.__doc__)
> >         return fset
> >     # getter and deleter can be defined the same way!
>
> > # -------- Example -------
>
> > class Foo(object):
> >     @property
> >     def bar(self):
> >         return self._bar
> >     @bar.setter
> >     def setbar(self, x):
> >         self._bar = '<%s>' % x
>
> > # -------- Interactive test -----
>
> > >>> foo = Foo()
> > >>> foo.bar = 3
> > >>> foo.bar
> > '<3>'
> > >>> foo.bar = 'oeufs'
> > >>> foo.bar
> > '<oeufs>'
>
> > Having fun'ly yours,
>
> Neat!
>
> Unfortunatly both this one and the one I posted before work when I try
> them out on the commandline but both fail when I try to use them in a
> module.  And I just can't figure out why.

This in more detail: Imaging mod.py:

import sys

_property = property

class property(property):
    """Python 2.6/3.0 style property"""
    def setter(self, fset):
        cls_ns = sys._getframe(1).f_locals
        for k, v in cls_ns.iteritems():
            if v == self:
                propname = k
                break
        cls_ns[propname] = property(self.fget, fset,
                                    self.fdel, self.__doc__)
        return fset


class Foo(object):
    @property
    def x(self):
        return self._x

    @x.setter
    def x(self, v):
        self._x = v + 1


Now enter the interpreter:
>>> import mod
>>> f = mod.Foo()
>>> f.x = 4
>>> f.x
4

I don't feel like giving up on this now, so close...



More information about the Python-list mailing list