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