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