multiple inheritance super()

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Mike Meyer

    #16
    Re: multiple inheritance super()

    "Michele Simionato" <michele.simion ato@gmail.com> writes:
    [color=blue]
    > adding methods on the fly and metaclasses could live pretty well
    > without
    > multiple inheritance. There would be no real loss
    > of power and hopefully less monstruosities such
    > a Zope 2. But maybe this is just wishful thinking ...[/color]

    Um, no real loss of power? Well, in the sense that all languages are
    turing-equivalent, maybe.

    My current project includes a small set of classes that all deal with
    web pages. The classes exist in three layers: the first layer is very
    abstract, and provides a general mechanism. The second layer adapts
    the general mechanasm to a specific case. The last layer provides
    application-specific functionality. The classes intercommunicat e, but
    are generally completely unrelated to each other except for the more
    concrete classes inheriting from the layer above.

    So far, so good - it's all simple single inheritance.

    Now, I have a class Utility that collects utility methods that are
    useful for dealing with web pages: extracting data, filling out forms,
    etc. These are provided as a mixin. The classes that need this
    functionality inherits from it as well as their parent. The classes
    that don't need it don't. This makes use of multiple inheritance.

    Without multiple inheritance, I would have had to make the Utility
    class a parent of all the most abstract classes. Some of the those
    classes don't need that functionality - but their children do, so they
    have to inherit from it. Children's needs shouldn't influence the
    implementation of the child - that's simply ugly. Also, it creates an
    apparent relationship between all the most abstract classes that
    doesn't really exist.

    Do you have a proposed solution that doesn't have these problems?

    <mike
    --
    Mike Meyer <mwm@mired.or g> http://www.mired.org/home/mwm/
    Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.

    Comment

    • Michele Simionato

      #17
      Re: multiple inheritance super()

      If I understand correcly you have a situation like this:

      Base

      |

      Parent1 Mixin
      | |
      | |
      Children1

      Base

      |

      Parent2 Mixin
      | |
      | |
      Children2


      Base

      |

      Parent3
      |
      |
      Children3

      The Base class is pretty general, Parent1, Parent2 and Parent3 are more
      specific, Children1 and Children2 requires the Mixin class, but
      Children3 does
      not require it.

      Let me note that this looks like a sensible design and that I agree
      that in simple
      situations multiple inheritance could be the simplest solution.
      Nevertheless 1)
      I am scared of the case where you have hundreds of methods coming from
      everywhere (ex. Zope) and 2) even in simple situations a solution
      without
      multiple inheritance is not that much worse.

      Various solutions (using pseudocode):

      1. use single inheritance and attach the mixin methods by hand:

      class Children2(Paren t2): pass

      for methodname, method in methods_of(Mixi n):
      setattr(Childre n2, methodname, method)

      if you think this is ugly, use a metaclass to attach the methods for
      you. This is probably still ugly, since it is akin to reimplementing
      multiple inheritance by hand. Still, it can be done, if you really
      want.

      2. use single inheritance and delegation. If "mixin" is a proxy to
      the methods in the mixin (for instance implemented as an attribute
      descriptor) you could do

      class Children2(Paren t2):
      mixin = Proxy(Mixin)

      c2 = Children2()

      and then c2.mixin.method (args) would actually call Mixin.method(c2 ,
      args).
      I like this solution since it is clear where methods come from and
      it scales
      better to complex situations (still if you have only 2 or 3 methods
      multiple inheritance could be pretty fine).

      3. think differently and use multimethods

      There are implementations of multimethods in Python (for instance in
      PEAK).
      This example looks like a good candidate for a multiple dispatch
      solution.
      You would use single inheritance and promote the mixin methods to
      multimethods. BTW, I think multimethods are pretty
      nifty and I would welcome them in standard Python.



      Michele Simionato

      Comment

      • Mike Meyer

        #18
        Re: multiple inheritance super()


        "Michele Simionato" <michele.simion ato@gmail.com> writes:

        I think you're replying to me, but you didn't include any indication
        so I can't be sure.
        [color=blue]
        > If I understand correcly you have a situation like this:
        >
        > Base
        >
        > |
        >
        > Parent1 Mixin
        > | |
        > | |
        > Children1
        >
        > Base
        >
        > |
        >
        > Parent2 Mixin
        > | |
        > | |
        > Children2
        >
        >
        > Base
        >
        > |
        >
        > Parent3
        > |
        > |
        > Children3[/color]

        Mostly right. What missing from the diagram is that there are three
        Base classes: Base1, Base2 and Base3. They have no methods in
        common.
        [color=blue]
        > The Base class is pretty general, Parent1, Parent2 and Parent3 are more
        > specific, Children1 and Children2 requires the Mixin class, but
        > Children3 does
        > not require it.[/color]

        At least one ParentX also uses Mixin.
        [color=blue]
        > Let me note that this looks like a sensible design and that I agree
        > that in simple
        > situations multiple inheritance could be the simplest solution.[/color]

        Thank you.
        [color=blue]
        > Nevertheless 1) I am scared of the case where you have hundreds of
        > methods coming from everywhere (ex. Zope) and[/color]

        Any tool can be abused.
        [color=blue]
        > Various solutions (using pseudocode):
        > 1. use single inheritance and attach the mixin methods by hand:
        > 2. use single inheritance and delegation. If "mixin" is a proxy to
        > the methods in the mixin (for instance implemented as an attribute
        > descriptor) you could do[/color]

        These two are cases of what I was talking about when I referred to the
        Church-Turing thesis. Also, I don't see how they make the situation
        you are scared of above any better.
        [color=blue]
        > 3. think differently and use multimethods
        >
        > There are implementations of multimethods in Python (for instance in
        > PEAK).
        > This example looks like a good candidate for a multiple dispatch
        > solution.
        > You would use single inheritance and promote the mixin methods to
        > multimethods.[/color]

        I don't see how that would help at all. You haven't done anything
        about solving the base problem - that getting the methods into my
        classes cleanly needs multiple inheritance. Further, I don't need
        methods that are distinguished based on their arguments - they all
        take a fixed set of arguments, and operate on them and the state of
        the instance. None seem to be candidates for being multimethods. The
        mixin methods tend to provide general functionality, and get used in
        radically different places by the different child classes.

        You did miss the one alternative I considered: making the methods of
        Mixin stand-alone functions, and passing them extra arguments instead
        of using attributes of the instance. They would all then look like
        mixin_func(self .foo, self.bar, var, value). I decided that this wasn't
        as readable as inherting the methods.
        [color=blue]
        > BTW, I think multimethods are pretty nifty and I would welcome them
        > in standard Python.[/color]

        I wouldn't bet on it happening. They seem to violate "explicit is
        better than implicit".

        <mike
        --
        Mike Meyer <mwm@mired.or g> http://www.mired.org/home/mwm/
        Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.

        Comment

        • Michele Simionato

          #19
          Re: multiple inheritance super()

          Mike Meyer:
          [color=blue]
          > I think you're replying to me, but you didn't include any indication
          > so I can't be sure.[/color]

          Oops, sorry, yes, I was replying to you.
          [color=blue]
          > These two are cases of what I was talking about when I referred to the
          > Church-Turing thesis.[/color]

          Well, let me put it in this way. If a language can implement a
          missing feature easily, then you are not really missing a big thing.
          And the feature may not be provided by default for sake of semplicity
          and/or uniformity of style. For instance Python does not have
          repeat-until
          loops, case statement, ternary operator, etc. (obviously I am not
          advocating to remove multiple inheritance now, I am justing
          speculating, talking about an hypotetic new Python-like language).
          [color=blue]
          > Also, I don't see how they make the situation
          > you are scared of above any better.[/color]

          It would discourage some people from some abuses, in the same sense the
          absence of repeat-until, case statemente, ternary operator etc are
          working right now.
          [color=blue][color=green]
          > > 3. think differently and use multimethods[/color]
          >
          > I don't see how that would help at all. You haven't done anything
          > about solving the base problem - that getting the methods into my
          > classes cleanly needs multiple inheritance. Further, I don't need
          > methods that are distinguished based on their arguments - they all
          > take a fixed set of arguments, and operate on them and the state of
          > the instance. None seem to be candidates for being multimethods. The
          > mixin methods tend to provide general functionality, and get used in
          > radically different places by the different child classes.
          >
          > You did miss the one alternative I considered: making the methods of
          > Mixin stand-alone functions, and passing them extra arguments instead
          > of using attributes of the instance. They would all then look like
          > mixin_func(self .foo, self.bar, var, value). I decided that this wasn't
          > as readable as inherting the methods.[/color]


          Uhm? I do not follow you. Multimethods would dispatch according
          to the type and would act differently on the childrens, dependending
          on their state. Perhaps I would need more information to understand
          what
          you have in mind.

          But at the end my point is "I would not feel much more constrained
          in expressivity if I did not have multiple inheritance in Python,
          and actually I have found out that the more I use OOP, the less I
          use inheritance".

          Just curious if others had a similar experience.

          Michele Simionato

          Comment

          • Mike Meyer

            #20
            Re: multiple inheritance super()

            "Michele Simionato" <michele.simion ato@gmail.com> writes:[color=blue]
            > Mike Meyer:[color=green]
            >> I think you're replying to me, but you didn't include any indication
            >> so I can't be sure.[/color]
            >
            > Oops, sorry, yes, I was replying to you.
            >[color=green]
            >> These two are cases of what I was talking about when I referred to the
            >> Church-Turing thesis.[/color]
            >
            > Well, let me put it in this way. If a language can implement a
            > missing feature easily, then you are not really missing a big thing.
            > And the feature may not be provided by default for sake of semplicity
            > and/or uniformity of style. For instance Python does not have
            > repeat-until
            > loops, case statement, ternary operator, etc. (obviously I am not
            > advocating to remove multiple inheritance now, I am justing
            > speculating, talking about an hypotetic new Python-like language).
            >[color=green]
            >> Also, I don't see how they make the situation
            >> you are scared of above any better.[/color]
            >
            > It would discourage some people from some abuses, in the same sense the
            > absence of repeat-until, case statemente, ternary operator etc are
            > working right now.[/color]

            These two points are working at cross purposes. If you can implement a
            missing feature easily, then it doesn't do much to discourage abuses
            of that feature.
            [color=blue][color=green][color=darkred]
            >> > 3. think differently and use multimethods[/color]
            >>
            >> I don't see how that would help at all. You haven't done anything
            >> about solving the base problem - that getting the methods into my
            >> classes cleanly needs multiple inheritance. Further, I don't need
            >> methods that are distinguished based on their arguments - they all
            >> take a fixed set of arguments, and operate on them and the state of
            >> the instance. None seem to be candidates for being multimethods. The
            >> mixin methods tend to provide general functionality, and get used in
            >> radically different places by the different child classes.
            >>
            >> You did miss the one alternative I considered: making the methods of
            >> Mixin stand-alone functions, and passing them extra arguments instead
            >> of using attributes of the instance. They would all then look like
            >> mixin_func(self .foo, self.bar, var, value). I decided that this wasn't
            >> as readable as inherting the methods.[/color]
            >
            > Uhm? I do not follow you. Multimethods would dispatch according
            > to the type and would act differently on the childrens, dependending
            > on their state. Perhaps I would need more information to understand
            > what
            > you have in mind.[/color]

            Ok, let's take a typical Mixin example. All the classes work with HTML
            pages rendered as soup. Some of them only deal with one page, others
            walk through multiple pages to find some specific bit of
            information. Each of them stores the page it's currently working on in
            the attribute page.

            The get_value method of Mixin extracts a string from self.page. You
            pass it a string, it invokes methods of self.page to locate a string
            that stands in a fixed relation to the string you passed in to it, and
            returns the found string.

            I don't see how this could be made a multimethod. What it does doesn't
            change depending on selfs type. This example could trivially have been
            done as a standalone function, as it only uses one attribute. Others
            use more, say filling out forms based on a dictionary attribute, or
            some such.
            [color=blue]
            > But at the end my point is "I would not feel much more constrained
            > in expressivity if I did not have multiple inheritance in Python,
            > and actually I have found out that the more I use OOP, the less I
            > use inheritance".
            >
            > Just curious if others had a similar experience.[/color]

            No, and yes. I think that using less inheritance as you get more
            practice with it is a common thing. At first, it seems very cool, and
            you're tempted to use it for everything. Then you find the problems
            that this creates, and back off from it some. On the other hand, as my
            understanding of inheritance deepened, I found myself using multiple
            inheritance more, not less. Mostly, it's for mixins. Sometimes, I
            really do need objects that have multiple types.

            <mike
            --
            Mike Meyer <mwm@mired.or g> http://www.mired.org/home/mwm/
            Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.

            Comment

            • Steven Bethard

              #21
              Re: multiple inheritance super()

              Michele Simionato wrote:[color=blue]
              > I have found out that the more I use OOP, the less I
              > use inheritance"
              >
              > Just curious if others had a similar experience.[/color]

              Definitely. Though I think that's partly because I came from a Java
              background where it's a little more ingrained. Since Python relies
              heavily on duck-typing, a lot of cases where I would subclass in Java I
              don't in Python. In Python, I pretty much only create an inheritance
              hierarchy when I discover that two independent classes are sharing the
              same code.

              STeVe

              Comment

              Working...