Enhanced property decorator
Gabriel Genellina
gagsl-py2 at yahoo.com.ar
Tue Sep 2 03:26:36 EDT 2008
En Mon, 25 Aug 2008 22:45:36 -0300, Daniel <millerdev at gmail.com> escribió:
> I've often been frustrated by the inability of the built-in property
> descriptor to handle anything other than a read-only property when
> used as a decorator. Furthermore, read/write/delete properties take
> their doc-string and property definition at a non-intuitive and
> awkward place (after the getter/setter/delter functions). The
> following are three possible solutions to this problem (inspired by
> message http://groups.google.com/group/comp.lang.python/msg/9a56da7ca8ceb7c7).
> I don't like the solution in that thread because it uses apply() which
> will go away in Python 3.
>
> Solution 1: new built-in function/descriptor
>
> def prop(func):
> funcs = dict(enumerate(func()))
> return property(funcs[0], funcs[1], funcs.get(2), func.__doc__)
>
> class Test(object):
> @prop
> def test():
> """test doc string"""
> def fget(self):
> return self._test
> def fset(self, value):
> self._test = value
> def fdel(self):
> del self._test
> return fget, fset, fdel
>
> Of course the name (prop) could be changed... I couldn't think of
> anything more concise.
>
> Pros:
> (1) encapsulation of property logic inside function namespace,
> preventing clutter in class namespace.
> (2) doc string appears in a more natural place, before getter/setter/
> delter logic, as in classes and functions.
>
> Cons:
> (1) additional built-in name.
> (2) duplication/boilerplate in return line (DRY violation).
(Some days late, sorry...) I like the variant below, based on your code. It avoids issue (2) by using locals(). Works with Python 3.0 too - and don't use tricks like sys._getframe or sys.settrace:
def defproperty(func):
impls = func()
return property(doc=func.__doc__, **impls)
class Test(object):
@defproperty
def test():
"""test doc string"""
def fget(self):
return self._test
def fset(self, value):
self._test = value
def fdel(self):
del self._test
return locals()
--
Gabriel Genellina
More information about the Python-list
mailing list