OO issues in python

Bruno Desthuilliers bdesth.tagada at tsoin-tsoin.free.fr
Wed Dec 17 13:05:14 CET 2003


Ali El Dada wrote:
> hi all:
> 
> in python, when a class, say Father, has a member that itself is an 
> instance of another class, say Child, an instance of Father actually 
> only has a reference to a Child, not the Child object itself, right?

I'm not sure I get the point. With Python, you only have symbols that 
are bounds to objects.

> because i know that in eiffel they give the programmer the 2 options, 
> the second being implemented with an additional keyword (expanded) so as 
> the eiffel documentation says,
> 
> "Consider the example of a class covering the notion of car. Many cars 
> share the same originating_plant , but an engine belongs to just one 
> car. References represent the modeling relation "knows about"; 
> subobjects, as permitted by expanded types, represent the relation "has 
> part", also known as aggregation. The key difference is that sharing is 
> possible in the former case but not in the latter"

No such thing in Python. But it comes down to :
1/ an object A is 'shared' by many others B* (composition) :
you instanciate A, and pass it to each B that needs to 'know about' it.

2/ an object A is 'part of' an object B (aggregation) :
B instanciate A, and no one else keeps a reference to A.


> the reason why i'm asking is that i want my Child() instance to know 
> things about the parent without having to explicitly pass them as 
> arguments. 

This seems quite a different problem. AFAICT, the Eiffel mechanism you 
mention don't let 'part' objects know anything about the object that 
'own' them (I may be wrong since I don't know Eiffel that much, but...).

> this is not working :(

I can't see how it could work. A object instance can only know what you 
let it know, so unless you pass it a ref to another object, it can't 
know nothing about it.

> eg code that doesn't work:
> 
> class Father:
> 
>    def __init__(self):
>       self.a = 'foo'
>       self.son = Child()
> 
> class Child:
> 
>    def __init__(self):
>       print f.a
where is this 'f' coming from ?-)

> 
> f = Father()
> 
How would you expect the Child *class* to know anything about a symbol 
that is yet unbound ?

You have two options :

1/
class Father:
   def __init__(self):
     self.a = a
     self.son = Child(self)

   def doIt(self):
     self.son.somethingElse()


class Child:
   def __init__(self, father):
     self.father = father
     print self.father.a

   def somethingElse(self):
     print self.father.a


2/
class Father:
   def __init__(self):
     self.a = a
     self.son = Child(self)

   def doIt(self):
     self.son.somethingElse(self)


class Child:
   def __init__(self, father):
     print father.a

   def somethingElse(self, father):
     print father.a


Note that
- with the first solution, you create a circular reference between 
Father and Child instances - but Python now has a real GC that handle 
such situations, so this may not be a problem.

- with the second solution, you can pass any other Father-like object to 
a Child instance, which may or may not be a problem.

Now there is no "Good" or "Bad" solution, it depends on the problem at hand.

HTH
Bruno





More information about the Python-list mailing list