The python implementation of the "relationships between classes".

Jerry Zhang jerry.scofield at gmail.com
Thu Nov 10 13:06:18 EST 2011


2011/11/11 Tim Wintle <tim.wintle at teamrubber.com>

> On Thu, 2011-11-10 at 22:25 +0800, Jerry Zhang wrote:
> >
> >
> > 2011/11/10 Chris Angelico <rosuav at gmail.com>
> >         On Fri, Nov 11, 2011 at 12:58 AM, Jerry Zhang
> >         <jerry.scofield at gmail.com> wrote:
> >         > Cls_a:
> >         >     def __init__(self):
> >         >         self.at1 = 1
> >         > Cls_b:
> >         >     def __init__(self):
> >         >         self.com1 = Cls_a()
> >         >     def __del__(self):
> >         >         del self.com1
> >         > Is it a right implementation for composition?
> >
> >
> >         Yes, except that you don't need to explicitly del it. Python
> >         (at
> >         least, CPython) is reference-counted; your Cls_b object owns a
> >         reference to the Cls_a object, so (assuming nothing else has a
> >         reference) that Cls_a will be happily cleaned up when the
> >         Cls_b is.
> >
> >         Python doesn't really talk about "composition" etc. It's much
> >         simpler:
> >         everything's an object, and you have references to that
> >         object. A
> >         named variable is a reference to some object. A member on an
> >         object
> >         is, too. Whenever an object is expired, all objects that it
> >         references
> >         lose one reference, and if that was the sole reference, those
> >         objects
> >         get expired too. It's a change of thinking, perhaps, but not a
> >         difficult one in my opinion; and it's so easy to work with
> >         when you
> >         grok it.
> >
> >
> > Unfortunately there is a difference between composition and
> > aggregation in my real word, and my application really care this since
> > it is trying to simulate this real world model, so my system should
> > track this difference accurately, otherwise the system may not work
> > well.
>
> You might want to look into weak references:
> http://docs.python.org/library/weakref.html
>
> Although I agree with Chris that it sounds like your code might be
> easier with a change of perspective (I've not done much UML, but the way
> you're describing things sounds like a java-ish way of looking at it to
> me)
>
> > For example,
> > a. the Cls_arm and Cls_body may be composition, but not aggregation.
> > My app must ensure that " one arm instance only live with one body
> > instance, if the body instance die, the arm instance must die.
> >  b. the Cls_auto and the Cls_tyre may be aggregation. "One tyre still
> > can live even the auto is dead."
>
> That behaviour isn't really hard-coded as part of the language in
> python, as it's not required for memory management in the same way it
> would be in C++ or langauges without GCs.
>
> As long as no objects other than body objects hold a reference to arm
> objects then the arm object will be deleted.
>
> For The tyre object to be deleted when the auto object is deleted, there
> would have to be no references left to the tyre object. If there aren't
> any references then you can't know if it exists or not anyway, so the
> distinction isn't useful.
>

I just did an example code to describe what i am looking for.
/*------------------------------------------------------------------------------------------------*/
# ...

class Head:
    def __init__(self):
        self.size = 5

class Hat:
    def __init__(self):
        self.color = red
    def took_on(self, body):
        self.body = body
    def took_off(self, body):
        del self.body

class Body:
    def __init__(self):
        self.head = Head()
    def take_on_hat(self, hat):
        self.hat = hat
        hat.take_on(self)
    def take_off_hat(self):
        hat.take_off(self)
        del self.hat
    def go_to_heaven(self):
        take_off_hat(self)
        del self.head
/*----------------------------------------------------------------------------------------------------------*/

In this example, Head and body are COMPOSITION, which means
a. A head only live with one body, it can not live with other body. It can
not even live without body
b. If the body go to die, the head also go to die.

Body and Hat are aggregation, which means
a. A hat live isolate with body, its life circle is isolate
b. A hat only live with one body at a specific time, it can not live with
two body(association would be more than one)

So when the body die, the clean dead should include take_off Hat and del
Head, otherwise, the code definition is not prciselly describing the
relationship, which may cause a mess system, for example, a body has dead,
but one hat is still associated with a unreferenced body.
A point on this issue, maybe python is smart that the take_off_hat(self) is
not needed in go_to_heaven() method(i am not sure yet), but the del
self.head is sure needed, otherwise, we will have a no_body_head in our
ZODB, that is extremely horrible, right?

All of these points one, the four kinds of class relationship in UML
precisely describe the real word, if the implementation is not precisely,
you will have unexpected results.
Of course, python may be smart to achieve such goal with less effort, that
is why i am asking for a code example for all of the four relationships.

>
> > Meanwhile, I have a ZODB running, which stores all the living
> > objects.
>
> The ZODB is append only and stores all objects. Deleting references to
> an object (which would causes deletion of standard python objects) won't
> delete it from the zodb, it'll just delete the references.
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20111111/a385f727/attachment-0001.html>


More information about the Python-list mailing list