a Python person's experience with Ruby

Arnaud Delobelle arnodel at googlemail.com
Sun Dec 9 06:11:04 EST 2007


On Dec 9, 12:15 am, Bruno Desthuilliers
<bdesth.quelquech... at free.quelquepart.fr> wrote:
> Richard Jones a écrit :
>
>
>
> > Bruno Desthuilliers wrote:
>
> >>class A(object):
> >>   @apply
> >>   def a():
> >>     def fget(self):
> >>       return self._a
> >>     def fset(self, val):
> >>       self._a = val
> >>     return property(**locals())
> >>   def __init__(self):
> >>     self.a = "foo"
>
> > That property setup seems overly complicated. As far as I can see, it only
> > avoids defining the setter in the class namespace,
>
> Yes. That's mosly the point.
>
> > yet is more complicated
> > and obfuscated to boot ;)
>
> Well, that's your POV, so what can I say ? It's indeed a bit hackish,
> and requires a couple minutes of attention the first time you see it.
> And you just have to learn it once !-)

Perhaps 'return property(fget, fset)' would be easier to make sense of
than **locals()

> Now I'd certainly prefer something like:
>
> class A(object):
>     @propget
>     def a(self):
>       return self._a
>     @propset
>     def a(self, val):
>       self._a = val
>
> But until there's something similar *builtin*, I'll stick to the @apply
> trick.

At first sight, I like the look of this. Obviously I can't provide a
builtin implementation, but there's an easy way to achieve this.  It
uses sys._getframe but there is no need to fiddle with metaclasses:

from sys import _getframe

def _makeprop(frame, name, **d):
    p = frame.f_locals.get(name, None)
    args = {}
    if isinstance(p, property):
        args = dict(fget=p.fget, fset=p.fset, fdel=p.fdel,
doc=p.__doc__)
    args.update(d)
    return property(**args)

def propget(f):
    return _makeprop(_getframe(1), f.__name__, fget=f)

def propset(f):
    return _makeprop(_getframe(1), f.__name__, fset=f)

def propdel(f):
    return _makeprop(_getframe(1), f.__name__, fdel=f)

if __name__ == '__main__':
    class Foo(object):
        a = property(doc="mod10 attribute")
        @propget
        def a(self):
            return self._a
        @propset
        def a(self, a):
            self._a = a % 10
        @propdel
        def a(self):
            del self._a

    f = Foo()
    f.a = 42
    assert f.a == 42 % 10



More information about the Python-list mailing list