http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/205183 idiom
Carsten Haese
carsten at uniqsys.com
Tue Mar 18 05:04:59 EDT 2008
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,
--
Carsten Haese
http://informixdb.sourceforge.net
More information about the Python-list
mailing list