Re: Newbie: Why doesn't this work



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

.



Relevant Pages

  • Re: Form wont remember last value
    ... "Ken Snell (MVP)" wrote: ... "I am using the LName and FName parameters as the Control Source for ... Report SQL: ...
    (microsoft.public.access.formscoding)
  • Re: Table design and Normalization
    ... All these people share the facts that they have FName, LName, ..., so having ... > DteBrth ... > SocSecurNumb ...
    (microsoft.public.access.tablesdbdesign)
  • Re: Problem with DBD::Oracle on OS X
    ... "state, len, rcntelno, lname, fname, instdate, ". ... ID, mrf_group, t.discodate FROM customer@teadprd c inner join ...
    (perl.dbi.users)
  • Re: Problem with DBD::Oracle on OS X
    ... "state, len, rcntelno, lname, fname, instdate, ". ... ID, mrf_group, t.discodate FROM customer@teadprd c inner join ...
    (perl.dbi.users)
  • Problem with DBD::Oracle on OS X
    ... sqlPlus works just fine and I would have considered by DBD::Oracle install to be ok, ... "state, len, rcntelno, lname, fname, instdate, ". ...
    (perl.dbi.users)