On Mar 18, 6:03 am, Gabriel Rossetti <[EMAIL PROTECTED]> wrote: > 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
Also check out a related recipe that doesn't require returning locals() explicitly: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/410698 George -- http://mail.python.org/mailman/listinfo/python-list