Simple metaclass code failing

Piet van Oostrum piet at cs.uu.nl
Mon Jun 1 12:44:17 CEST 2009


>>>>> Piet van Oostrum <piet 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 <piet at cs.uu.nl>
URL: http://pietvanoostrum.com [PGP 8DAE142BE17999C4]
Private email: piet at vanoostrum.org



More information about the Python-list mailing list