Re: Newbie: Why doesn't this work
- From: "Gabriel Genellina" <gagsl-py2@xxxxxxxxxxxx>
- Date: Mon, 31 Dec 2007 15:36:45 -0200
En Mon, 31 Dec 2007 14:56:02 -0200, <ct60@xxxxxxx> 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
.
- References:
- Newbie: Why doesn't this work
- From: ct60
- Newbie: Why doesn't this work
- Prev by Date: Re: Bizarre behavior with mutable default arguments
- Next by Date: Re: Newbie: Why doesn't this work
- Previous by thread: Newbie: Why doesn't this work
- Next by thread: Re: Newbie: Why doesn't this work
- Index(es):
Relevant Pages
|