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 -- http://mail.python.org/mailman/listinfo/python-list