En Mon, 31 Dec 2007 14:56:02 -0200, <[EMAIL PROTECTED]> escribi�: > Hi Python Community: > > Despite my new-ness to Python I have alreadhy been able to do some (I > think) amazing things. It is a truly elegant and smart language. > > Yet, I can not seem to get a handle on something simple. > > I would like to make a class which has private varaiables fName and > lName. It should have a property "name" which can get or set a name. > Something like as follows: > > class Person: > def __init__(self, fName="", lName=""): > self.__fName = fName > self.__lName = lName > > def __getattr__(self, attr): > if attr == "name": > return self.__fName + " " + self.__lName > > def __setattr__(self, attr, value): > # this assumes that value is a tuple of first and last name > if attr == "name": > self.__fName, self.__lName = value
__getattr__ gets called when an attribute lookup fails in the "standard" places. Your version, when attr is not "name", does nothing - effectively returning None for *any* other attribute. You should raise an AttributeError instead: add this line after the if: raise AttributeError, attr __setattr__, on the other hand, is called with *any* attempt to set an attribute. Your version effectively makes Person "read only"; the only attribute you can set is "name". We could fix that, but there are better ways. Forget about __getattr__ and __setattr__ and use a property: class Person(object): def __init__(self, fName="", lName=""): self._fName = fName self._lName = lName def getName(self): return "%s %s" % (self._fName, self._lName) def setName(self, value): self._fName, self._lName = value name = property(getName, setName) Note that: - I've inherited Person from object. Person is then a "new-style" class, and only "new-style" classes support properties (and other goodies). - I've used _fName instead of __fName. The single _ is an indication to the outside "warning, this is an implementation detail, don't play with it". (Two underscores are (rarely) used when you want to minimize name collisions with subclasses.) - name is now a property, associated to the two functions getName and setName. It works the way you want: py> p = Person("John", "Smith") py> p.name 'John Smith' py> p.name = "Tom", "Sawyer" py> p.name 'Tom Sawyer' Something I don't like in this design, is that you can't assign the property to itself; p.name = p.name fails because the "set" expects a tuple and the "get" returns a single string. -- Gabriel Genellina -- http://mail.python.org/mailman/listinfo/python-list