Parametrized inheritance

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Dan Bullok

    Parametrized inheritance

    I have a couple of classes:
    class Base:
    ...

    class Sub(Base):
    ...


    I want to subclass Base and Sub, i.e. define classes:
    class MyBase(Base):
    ...

    class MySub(Sub):
    ...

    The inheritance looks like this:
    Base->MyBase
    ->Sub->MySub

    But I'd really like it to look like this:
    Base->MyBase->Sub->MySub

    i.e. define Sub as "class Sub(X)", where I can change X at the time of
    instantiation. Then I could define MySub as "class MySub(Sub(MyBas e))".
    (I hope that it's obvious that I'm looking for this effect, not this syntax)


    Of course, someone is going to ask "why?"

    I need to override a few members in Base. Sub is mostly fine as-is, so if I
    could have MySub=Sub(MyMBa se), that would be fine.






  • Mike C. Fletcher

    #2
    Re: Parametrized inheritance

    Dan Bullok wrote:
    ....
    [color=blue]
    >The inheritance looks like this:
    > Base->MyBase
    > ->Sub->MySub
    >
    >But I'd really like it to look like this:
    > Base->MyBase->Sub->MySub
    >
    >i.e. define Sub as "class Sub(X)", where I can change X at the time of
    >instantiatio n. Then I could define MySub as "class MySub(Sub(MyBas e))".
    >(I hope that it's obvious that I'm looking for this effect, not this syntax)
    >
    >[/color]
    Works quite nicely in Python 2.2 with only one minor change. In particular use of object as base for Base:
    [color=blue][color=green][color=darkred]
    >>> class Base(object):[/color][/color][/color]
    .... pass
    ....[color=blue][color=green][color=darkred]
    >>> class Sub( object ):[/color][/color][/color]
    .... pass
    ....[color=blue][color=green][color=darkred]
    >>> class MyBase( Base ):[/color][/color][/color]
    .... pass
    ....[color=blue][color=green][color=darkred]
    >>> class MySub( Sub, MyBase ):[/color][/color][/color]
    .... pass
    ....[color=blue][color=green][color=darkred]
    >>> MySub.mro()[/color][/color][/color]
    [<class '__main__.MySub '>, <class '__main__.Sub'> ,
    <class '__main__.MyBas e'>, <class '__main__.Base' >,
    <type 'object'>][color=blue][color=green][color=darkred]
    >>>[/color][/color][/color]

    You can use the super( ... ) built-in to provide really elegant support
    for mix-in classes overriding base-class operations cooperatively.

    BTW, you could have made Sub a sub-class of Base in the example above
    and *still* had it give you the desired method-resolution-order, (a nice feature of Python's multiple-inheritance mechanism, IMO). (I made Sub's parent object to make it clear how the inheritance works.)

    You can find more information about these kinds of patterns by searching for "Mix-In Class" and/or "Multiple Inheritance". Python 2.2 changed how multiple inheritance graphs are constructed in Python, BTW. If you used old-style classes the mro would have been [MySub, Sub, Base, MyBase, Base] IIRC.

    HTH,
    Mike

    _______________ _______________ _________
    Mike C. Fletcher
    Designer, VR Plumber, Coder





    Comment

    • Dan Bullok

      #3
      Re: Parametrized inheritance

      Mike C. Fletcher wrote:
      [color=blue]
      > You can find more information about these kinds of patterns by searching
      > for "Mix-In Class" and/or "Multiple Inheritance". Python 2.2 changed how
      > multiple inheritance graphs are constructed in Python, BTW. If you used
      > old-style classes the mro would have been [MySub, Sub, Base, MyBase, Base]
      > IIRC.[/color]

      Well, I thought of doing this, but after looking up resolution order (sec
      9.5.1 of the tutorial) I found that resolution is done "depth-first,
      left-to-right", In my example, that would have given [MySub, Sub, Base,
      MyBase, Base], but, I checked, using mro(), and found that it was indeed
      [MySub, Sub, MyBase, Base], just as I needed it. (thanks for the mro() tip
      - didn't know about that one). Unless I've gone crosseyed (possible, it's
      late), this is NOT depth-first, left-to-right. So is the tutorial out of
      date?


      Comment

      • Aahz

        #4
        Re: Parametrized inheritance

        In article <sNNJb.741891$F m2.670283@attbi _s04>,
        Dan Bullok <myfirstname@my lastname.com> wrote:[color=blue]
        >Mike C. Fletcher wrote:[color=green]
        >>
        >> You can find more information about these kinds of patterns by searching
        >> for "Mix-In Class" and/or "Multiple Inheritance". Python 2.2 changed how
        >> multiple inheritance graphs are constructed in Python, BTW. If you used
        >> old-style classes the mro would have been [MySub, Sub, Base, MyBase, Base]
        >> IIRC.[/color]
        >
        >Well, I thought of doing this, but after looking up resolution order (sec
        >9.5.1 of the tutorial) I found that resolution is done "depth-first,
        >left-to-right", In my example, that would have given [MySub, Sub, Base,
        >MyBase, Base], but, I checked, using mro(), and found that it was indeed
        >[MySub, Sub, MyBase, Base], just as I needed it. (thanks for the mro() tip
        >- didn't know about that one). Unless I've gone crosseyed (possible, it's
        >late), this is NOT depth-first, left-to-right. So is the tutorial out of
        >date?[/color]

        As Mike said, it's different for new-style classes. See

        --
        Aahz (aahz@pythoncra ft.com) <*> http://www.pythoncraft.com/

        Weinberg's Second Law: If builders built buildings the way programmers wrote
        programs, then the first woodpecker that came along would destroy civilization.

        Comment

        • Francis Avila

          #5
          Re: Parametrized inheritance

          #quote#
          Dan Bullok wrote in message ...
          Mike C. Fletcher wrote:
          [color=blue]
          > You can find more information about these kinds of patterns by searching
          > for "Mix-In Class" and/or "Multiple Inheritance". Python 2.2 changed how
          > multiple inheritance graphs are constructed in Python, BTW. If you used
          > old-style classes the mro would have been [MySub, Sub, Base, MyBase, Base]
          > IIRC.[/color]

          Well, I thought of doing this, but after looking up resolution order (sec
          9.5.1 of the tutorial) I found that resolution is done "depth-first,
          left-to-right", In my example, that would have given [MySub, Sub, Base,
          MyBase, Base], but, I checked, using mro(), and found that it was indeed
          [MySub, Sub, MyBase, Base], just as I needed it. (thanks for the mro() tip
          - didn't know about that one). Unless I've gone crosseyed (possible, it's
          late), this is NOT depth-first, left-to-right. So is the tutorial out of
          date?
          #endquote#

          I just looked and, yes indeed, it is out of date (file a bug report).
          Python 2.2 used this mro, which was changed in 2.3. 2.3 uses a so-called
          'C3' mro, which is a bit more complex. See
          http://www.python.org/2.3/mro.html.

          The best documentation on Python classes WRT the new-style changes is an
          essay by Guido at http://www.python.org/2.2.2/descrintro.html. It says 2.2,
          but it mentions 2.3 changes as inline addendums.

          Odd thing is, filename is "descriptor intro" yet it doesn't mention
          descriptors. There's a good reference on the madness that is descriptors at
          http://users.rcn.com/python/download/Descriptor.htm.
          --
          Francis Avila

          Comment

          Working...