[Tutor] two questions..

dman dsh8290@rit.edu
Wed, 14 Nov 2001 18:11:16 -0500


On Wed, Nov 14, 2001 at 12:39:08PM -0800, Israel Evans wrote:
| 	
| 
| Hello everyone...  I'm stumped by what are probably two simple questions
| that may be aimed at OOP more than Python but since I'm using the language,
| I'll need to know how python handles these sorts of things.
| 
| 
| anyway, here goes...
| 
|  1.     If I have a hierarchy of classes, the children of which derive a
| particular attribute from an attribute present in the parent, and I want to
| set up a distribution pattern for that attribute to determine which children
| get what amounts of said attribute, how do I alter that pattern for one
| particular child and still save the original pattern for later use.  This
| would be something like adding a temporary modifier to the chosen child that
| can be removed at a later date.  

Some of this is a bit confusing to me :
    if an attribute is defined in a base class, all instances of
    subclasses will have that attribute.

    if that attribute is an *instance attribute* then each instance
    has its own copy and can be changed without affecting other
    instances

    if the attribute is a *class attribute* ("static" in C++ and Java)
    then it is shared by all instances because the attribute belongs
    in the class.
 
|     To restate, how does one add a modifier to an object that can later be
| removed.  I'd also like to access a list of these modifiers.

If you want to restore the old value of a reference, you need to store
the old value somewhere before overwriting it.


Hmm, suppose you had :

class B :
    cmember = 1

class C( B ) :
    def foo( self ) :
        print self.cmember
    def bar( self ) :
        self.cmember = 5
    def baz( self ) :
        del self.cmember

>>> o = C()
>>> o.foo()
1
>>> o.bar()
>>> o.foo()
5
>>> o.baz()
>>> o.foo()
1
>>>


Is this what you are looking for?

What happens here is the class object "B" has an attribute named
"cmember".  In the first call to foo(), the search for self.cmember
finds B.cmember first.  When I called bar() I created a reference in
the instance (not the class) and gave it a value.  Thus the next call
to foo() finds self.cmember first, and never gets to B.cmember (which
hasn't changed).  Then I delete that reference in baz() so that foo()
finds B.cmember like it did the first time.

| 2.    This one is really making my head hurt at the moment.   When I have
| two objects that come with their own attribute and functions, and make them
| work together, that third thing is something like a new object, but what
| about the particular point at which the two objects connect?   Take for
| example the upper arm and the lower arm.  Where they connect is called the
| elbow.  Would this be a separate object?  Would the Arm object be compose of
| these along with the hand, wrist and shoulder?  When the lines between
| objects get fuzzy, what do you do?

I think you mean :

class A :
    def a( self ) :
        print "a"

class B :
    def b( self ) :
        print "b"

class Composer : # note, no inheritance
    def __init__( self ) :
        self._a = A()
        self._b = B()

    def a( self ) :
        print "composer a"
        self._a.a()
        print "composer a some more"

    def b( self ) :
        print "composer b"
        self._b.b()
        print "composer b some more"

o = Composer()

You want to know what the Composer instance is?  It is just an object.
The fact that is uses composition instead of inheritance is mainly an
implementation detail.  Often times, though, composition is preferred
over inheritance because it reduces icky inheritance trees.  In
python, composition is much easier since __getattr__ and __setattr__
can be written to automatically defer implementation to the internal
objects without actually writing all the methods.

I highly recommend the book "Design Patterns" by the Gang of Four (so
they're called, I forget their real names).  It discusses many design
patterns for OO software.  One of the patterns is called "Composite"
which is similar to (though not exactly) what is shown above.

HTH,
-D