http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/205183 idiom

Gabriel Rossetti gabriel.rossetti at mydeskfriend.com
Tue Mar 18 06:03:15 EDT 2008


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



More information about the Python-list mailing list