Simple metaclass code failing
LittleGrasshopper
seattlehanks at yahoo.com
Mon Jun 1 19:14:05 EDT 2009
On Jun 1, 3:44 am, Piet van Oostrum <p... at cs.uu.nl> wrote:
> >>>>> Piet van Oostrum <p... at cs.uu.nl> (I) wrote:
> >I> But your class definition:
> >I> class C3(C1, C2):
> >I> says that C1 should be before C2. Conflict!!
> >I> Change it to class C3(C2, C1):
>
> Of course the C1 is then superfluous.
>
> I wonder why you want this. What is the problem you want to solve?
>
> Apart from the metaclasses (that you still can use with `class C3(C2)')
> I could think of the following use case:
>
> class C1(object):
> def m1(self):
> return 'C1.m1'
>
> class C2(C1):
> # override m1
> def m1(self):
> return 'C2.m1'
> def m2(self):
> return 'C2.m2'+self.m1()
>
> class C3(C1, C2):
> def test(self):
> print self.m1()+self.m2()
>
> i.e. in C3 we `ignore' the override of m1 in C2 but still want to make
> use of the m2 from C2.
>
> The question that arises then is: the self.m1() inside m2, which m1
> should it use? For an instance of C3 it would use C1.m1, but for an
> instance of C2 it would use C2.m2.
>
> However, every instance of C3 can also be considered an instance of C2,
> (Liskov substitution principle), therefore there is a conflict. That is
> exactly the conflict that the MRO signals.
>
> If you want that kind of behaviour it can be solved by using a mixin
> class for the m2 method:
>
> class C1(object):
> __metaclass__ = M1
> def m1(self):
> return 'C1.m1'
> class Cmix(object):
> def m2(self):
> return 'C2.m2'+self.m1()
> class C2(C1, Cmix):
> __metaclass__ = M2
> # override m1
> def m1(self):
> return 'C2.m1'
> class C3(C1, Cmix):
> __metaclass__ = M3
> def test(self):
> print self.m1()+self.m2()
>
> --
> Piet van Oostrum <p... at cs.uu.nl>
> URL:http://pietvanoostrum.com[PGP 8DAE142BE17999C4]
> Private email: p... at vanoostrum.org
Your discussion of this scenario, why it justifiably fails, and the
alternative solution using a mixing, is all excellent. I am going to
keep this for future reference. I am at a stage of my Python journey
that some of these things seem rather mysterious, so I especially
appreciate this very detailed discussion.
To answer your question, I actually got this hierarchy directly from
Guido's paper on class unification that came out with 2.2.3.
More information about the Python-list
mailing list