http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/205183 idiom
George Sakkis
george.sakkis at gmail.com
Tue Mar 18 14:20:58 EDT 2008
On Mar 18, 6:03 am, Gabriel Rossetti
<gabriel.rosse... at mydeskfriend.com> wrote:
> Carsten Haese wrote:
> > On Tue, 2008-03-18 at 09:06 +0100, Gabriel Rossetti wrote:
>
> >> Hello,
>
> >> I am reading core python python programming and it talks about using the
> >> idiom
> >> described on
> >>http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/205183.
>
> >> I'm using python 2.5.1 and if I try :
>
> >> class MyClass(object):
> >> def __init__(self):
> >> self._foo = "foo"
> >> self._bar = "bar"
>
> >> @property
> >> def foo():
> >> doc = "property foo's doc string"
> >> def fget(self):
> >> return self._foo
> >> def fset(self, value):
> >> self._foo = value
> >> def fdel(self):
> >> del self._foo
> >> return locals() # credit: David Niergarth
>
> >> @property
> >> def bar():
> >> doc = "bar is readonly"
> >> def fget(self):
> >> return self._bar
> >> return locals()
>
> >> like suggested in the book (the decorator usage) I get this :
>
> >> >>> a=MyClass()
> >> >>> a.foo
> >> Traceback (most recent call last):
> >> File "<stdin>", line 1, in <module>
> >> TypeError: foo() takes no arguments (1 given)
>
> >> but if I write it just like on the web page (without the decorator, using "x = property(**x())" instead) it works :
>
> >> >>> a = MyClass()
> >> >>> a.foo
> >> 'foo'
>
> >> does anyone have an idea as of why this is happening?
>
> > You're mixing two completely different approaches of building a
> > property. If that code is actually in the book like that, that's a typo
> > that you should mention to the author.
>
> > The @property decorator can only be used to turn a single getter
> > function into a read-only attribute, because this:
>
> > @property
> > def foo(...):
> > ...
>
> > is the same as this:
>
> > def foo(...):
> > ...
> > foo = property(foo)
>
> > and calling property() with one argument builds a property that has just
> > a getter function that is the single argument you're giving it.
>
> > The recipe you're referring to uses a magical function that returns a
> > dictionary of getter function, setter function, deleter function, and
> > docstring, with suitable key names so that the dictionary can be passed
> > as a keyword argument dictionary into the property() constructor.
> > However, that requires the magical foo=property(**foo()) invocation, not
> > the regular decorator invocation foo=property(foo).
>
> > HTH,
>
> I was able to get it t work with the decorator by doing this :
>
> def MyProperty(fcn):
> return property(**fcn())
>
> and using it like this :
>
> class MyClass(object):
> def __init__(self):
> self._foo = "foo"
> self._bar = "bar"
>
> @MyProperty
> def foo():
> doc = "property foo's doc string"
> def fget(self):
> return self._foo
> def fset(self, value):
> self._foo = value
> def fdel(self):
> del self._foo
> return locals() # credit: David Niergarth
>
> @MyProperty
> def bar():
> doc = "bar is readonly"
> def fget(self):
> return self._bar
> return locals()
>
> Cheers,
> Gabriel
Also check out a related recipe that doesn't require returning
locals() explicitly: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/410698
George
More information about the Python-list
mailing list