Re: python object model

scharf@EMBL-Heidelberg.DE
Tue, 30 Aug 1994 20:34:18 +0100

> I wrote yesterday (at the end of a day of bloody battle with C++...):

I'm also a big C++ hacker :-)

>
> I'm not sure I have an opinion on the use of 'pseudo' members, as shown in your
> 'Square.py' example. I'm already used to using parenthesis to fetch a member's
> value; your use of __getattr__ to fire off computation when a pseudo method is
> accessed ('object.area' triggers a method to compute the value) avoids typing
> parenthesis after a member name. Definately convenient, but not a big deal to
> me (but then I've already been corrupted by C++ :-0).
>

from math import sqrt

class Square:
side=0
def __setattr__(self,name,v):
if name=='side':
# let's check if side is what we think is should be:
# side may only be positive number....
if v < 0:
raise RuntimeError, "%s%d < 0" %(name,v)
if name=='area':
# area may only be positive number....
if v < 0:
raise RuntimeError, "%s=%d < 0" %(name,v)
# we don't set area but side :-)
self.__setslot__('side',sqrt(v))
else:
self.__setslot__(name,v)

def __getattr__(self,name):
if name=='area':
# area is a pseudo attribute, it's calculated on the fly
return self.side * self.side
else:
raise AttributeError, name

square.side=10
print square.side # 10
print square.area # 100 pseudo attribute is called
square.area=10 # sets side instead of area
print square.side # sqrt(10)
print square.area # 100
square.area=-1 # AttributeError ! (area out of range)

I'm also not shure if this is a good or bad feature! To call a trigger when
geting or seting a variable can change the the semantics:

assigning to area changes the value of side!

On the other hand, carefully used, this feature can make programs more
safe. Like Square not allowing the area and side being a negative number.

It might be, that in an initial design one allows assignment to self.side,
later on feels the need of calling a method when the value of self.side
changes. To be prepared for such changes, I usually have a Set and Get method
for each member and never assign directely. Most of these methods don't do
anything special. Whith this new paradigm one can simply assign or access an
attribute - if we need a trigger we can add it later. I think this makes
(proto)typeing faster :-)

Michael