Inheritance but only partly?

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

    Inheritance but only partly?

    Let's say I have a class X which has 10 methods.

    I want class Y to inherit 5 of them.

    Can I do that? Can I do something along the lines of super(Y, exclude
    method 3 4 7 9 10) ?
  • Gary Herron

    #2
    Re: Inheritance but only partly?

    process wrote:
    Let's say I have a class X which has 10 methods.
    >
    I want class Y to inherit 5 of them.
    >
    Can I do that? Can I do something along the lines of super(Y, exclude
    method 3 4 7 9 10) ?
    >
    --

    >
    No.

    But why do yo care? You can just ignore the 5 you don't want -- their
    existence costs you nothing in either memory or execution speed.

    You can also redefine the ones you don't want inherited:

    class A:
    def DontInheritMe(s elf, ...):
    ...

    Class B(A):
    def DontInheritMe(s elf, ...):
    raise NotImplementedE rror // Or some such


    Gary Herron

    Comment

    • Matimus

      #3
      Re: Inheritance but only partly?

      On Oct 2, 1:16 pm, process <circularf...@g mail.comwrote:
      Let's say I have a class X which has 10 methods.
      >
      I want class Y to inherit 5 of them.
      >
      Can I do that? Can I do something along the lines of super(Y, exclude
      method 3 4 7 9 10) ?
      I think the noral way of doing that is to split the origional class
      into two classes.

      What you have:

      class BaseClass(objec t):

      def method0:
      pass

      def method1:
      pass

      def method2:
      pass

      ...

      def method9:
      pass

      What you need:


      class BaseClassWant(o bject):
      def method0:
      pass

      def method1:
      pass

      ...

      def method4:
      pass

      class BaseClassDontWa nt(object):
      def method5:
      pass

      def method6:
      pass

      ...

      def method9:
      pass

      class BaseClass(BaseC lassWant, BaseClassDontWa nt): # same as BaseClass
      above
      pass

      class YourClass(BaseC lassWant):
      pass


      Matt

      Comment

      • Aaron \Castironpi\ Brady

        #4
        Re: Inheritance but only partly?

        On Oct 2, 3:16 pm, process <circularf...@g mail.comwrote:
        Let's say I have a class X which has 10 methods.
        >
        I want class Y to inherit 5 of them.
        >
        Can I do that? Can I do something along the lines of super(Y, exclude
        method 3 4 7 9 10) ?
        That implies that the 5 you do include don't rely on or call the 5 you
        don't. Otherwise you have to inherit them. Then you can refactor
        them into:

        class X5YouDo: ...
        class X5YouDont: ...
        class X( X5YouDo, X5YouDont ): ...
        class Y( X5YouDo ): ...

        If you're looking for restricted visibility, Python does not have it.
        It's just handcuffs, and makes things you can't do.

        After all, nothing would stop you user from calling:

        y= Y()
        X5YouDont.DontI nheritMe( y, args )

        to get at the uninherited methods.

        Comment

        • Gary Herron

          #5
          Re: Inheritance but only partly?

          Gary Herron wrote:
          process wrote:
          >
          >Let's say I have a class X which has 10 methods.
          >>
          >I want class Y to inherit 5 of them.
          >>
          >Can I do that? Can I do something along the lines of super(Y, exclude
          >method 3 4 7 9 10) ?
          >>
          >--
          >http://mail.python.org/mailman/listinfo/python-list
          >>
          >>
          No.
          >
          But why do yo care? You can just ignore the 5 you don't want -- their
          existence costs you nothing in either memory or execution speed.
          >
          You can also redefine the ones you don't want inherited:
          >
          class A:
          def DontInheritMe(s elf, ...):
          ...
          >
          Class B(A):
          def DontInheritMe(s elf, ...):
          raise NotImplementedE rror // Or some such
          >
          >
          Gary Herron
          >
          --

          >
          Here's another (very Python) possibility

          class Base:
          class m1(self, ...):
          ...
          class m2(self, ...):
          ...

          class NotInheritable:
          class m3(self, ...):
          ...

          class A(Base, NotInheritable) ;
          ...

          class B(Base):
          ...



          Comment

          • bearophileHUGS@lycos.com

            #6
            Re: Inheritance but only partly?

            Gary Herron:
            You can also redefine the ones you don't want inherited:
            class A:
            def DontInheritMe(s elf, ...):
            ...
            Class B(A):
            def DontInheritMe(s elf, ...):
            raise NotImplementedE rror // Or some such
            I have never used something like this, but the OP may use a masking
            class too:

            class A(object):
            def m1(self): pass
            def m2(self): pass
            def m3(self): pass
            def m4(self): pass

            class Mask(object):
            def m3(self): raise NotImplementedE rror
            def m4(self): raise NotImplementedE rror

            class B(Mask, A):
            pass

            a = A()
            a.m1()
            a.m2()
            a.m3()
            a.m4()

            b = B()
            b.m1()
            b.m2()
            b.m3() # raises
            b.m4() # raises

            In a language without multiple inheritance you need a different trick,
            I presume.
            What's the name of this python design pattern? :-)

            Bye,
            bearophile

            Comment

            • greg

              #7
              Re: Inheritance but only partly?

              bearophileHUGS@ lycos.com wrote:
              class Mask(object):
              def m3(self): raise NotImplementedE rror
              def m4(self): raise NotImplementedE rror
              What's the name of this python design pattern? :-)
              Don't know. Perhaps we could call it the FigLeaf pattern
              (covering up what you don't want seen)?

              There's another possibility that's even more pythonish
              (I won't say pythonic, since it's not necessarily
              a *recommended* thing to do):

              class A:
              m1 = B.__dict__['m1']
              m2 = B.__dict__['m2']
              ...

              I propose calling this the Magpie pattern (stealing
              the shiny baubles you want and hiding them away in
              your own nest).

              --
              Greg

              Comment

              • Peter Otten

                #8
                Re: Inheritance but only partly?

                greg wrote:
                >class Mask(object):
                >def m3(self): raise NotImplementedE rror
                >def m4(self): raise NotImplementedE rror
                >
                >What's the name of this python design pattern? :-)
                >
                Don't know. Perhaps we could call it the FigLeaf pattern
                (covering up what you don't want seen)?
                Braghettone ;)

                Comment

                • Michele Simionato

                  #9
                  Re: Inheritance but only partly?

                  On Oct 2, 10:16 pm, process <circularf...@g mail.comwrote:
                  Let's say I have a class X which has 10 methods.
                  >
                  I want class Y to inherit 5 of them.
                  >
                  Can I do that? Can I do something along the lines of super(Y, exclude
                  method 3 4 7 9 10) ?
                  Don't use inheritance, use delegation or just copy the methods you
                  need:

                  class A(object):
                  def meth_a(self):
                  pass

                  class B(object):
                  meth_a = A.meth_a.im_fun c


                  IMO, if you have methods that you want to use in different classes,
                  this is hint that
                  you are in need of generic functions. See this blog post for an
                  example:


                  Comment

                  • Tim Rowe

                    #10
                    Re: Inheritance but only partly?

                    2008/10/2 process <circularfunc@g mail.com>:
                    Let's say I have a class X which has 10 methods.
                    >
                    I want class Y to inherit 5 of them.
                    >
                    Can I do that?
                    As others have said, no. What nobody seems to have said yet is why. If
                    Y descends from X, you are saying that Y is an X; that a Y can be used
                    anywhere an X can. If Y doesn't support some methods of X then it is
                    *not* an X, and *can't* be used anywhere an X can.

                    Rather than looking at workarounds, as others have, I think you need
                    to go back to your design and work out what's gone wrong that you
                    /want/ to descend Y from X. Your present design is wrong, plain and
                    simple. Working around it won't fix that.

                    --
                    Tim Rowe

                    Comment

                    • Simon Brunning

                      #11
                      Re: Inheritance but only partly?

                      2008/10/3 Tim Rowe <digitig@gmail. com>:
                      As others have said, no. What nobody seems to have said yet is why. If
                      Y descends from X, you are saying that Y is an X; that a Y can be used
                      anywhere an X can. If Y doesn't support some methods of X then it is
                      *not* an X, and *can't* be used anywhere an X can.
                      See <http://en.wikipedia.or g/wiki/Liskov_substitu tion_principle> .

                      --
                      Cheers,
                      Simon B.
                      simon@brunningo nline.net

                      GTalk: simon.brunning | MSN: small_values | Yahoo: smallvalues |
                      Twitter: brunns | Facebook: http://tinyurl.com/6f47zo

                      Comment

                      • Steven D'Aprano

                        #12
                        Re: Inheritance but only partly?

                        On Fri, 03 Oct 2008 03:32:52 -0700, Michele Simionato wrote:
                        IMO, if you have methods that you want to use in different classes, this
                        is hint that
                        you are in need of generic functions. See this blog post for an example:
                        >
                        http://www.artima.com/weblogs/viewpo...?thread=237764

                        That's a very interesting article, but I'm afraid I don't understand what
                        makes them "generic functions" as opposed to just functions. Your simple
                        generic example:


                        from pkgutil import simplegeneric

                        @simplegeneric
                        def print_out(self, text, *args):
                        if args:
                        text = text % args
                        print >self.stdout, text
                        # and similar for print_err and readln_in

                        class FileOut(object) :
                        def __init__(self):
                        self.stdout = file('out.txt', 'w')

                        print_out(FileO ut(), 'writing on file') # prints a line on out.txt



                        doesn't seem to do anything extra that the following would do:


                        def print_out2(obj, text, *args):
                        if args:
                        text = text % args
                        print >obj.stdout, text

                        class FileOut2(object ):
                        def __init__(self):
                        self.stdout = file('out2.txt' , 'w')

                        print_out(FileO ut2(), 'writing on file')



                        What's the difference?


                        --
                        Steven

                        Comment

                        • George Sakkis

                          #13
                          Re: Inheritance but only partly?

                          On Oct 3, 11:56 pm, Steven D'Aprano <st...@REMOVE-THIS-
                          cybersource.com .auwrote:
                          On Fri, 03 Oct 2008 03:32:52 -0700, Michele Simionato wrote:
                          IMO, if you have methods that you want to use in different classes, this
                          is hint that
                          you are in need of generic functions. See this blog post for an example:
                          >>
                          That's a very interesting article, but I'm afraid I don't understand what
                          makes them "generic functions" as opposed to just functions. Your simple
                          generic example:
                          >
                          from pkgutil import simplegeneric
                          >
                          @simplegeneric
                          def print_out(self, text, *args):
                              if args:
                                  text = text % args
                              print >self.stdout, text
                          # and similar for print_err and readln_in
                          >
                          class FileOut(object) :
                              def __init__(self):
                                  self.stdout = file('out.txt', 'w')
                          >
                          print_out(FileO ut(), 'writing on file') # prints a line on out.txt
                          >
                          doesn't seem to do anything extra that the following would do:
                          >
                          def print_out2(obj, text, *args):
                              if args:
                                  text = text % args
                              print >obj.stdout, text
                          >
                          class FileOut2(object ):
                              def __init__(self):
                                  self.stdout = file('out2.txt' , 'w')
                          >
                          print_out(FileO ut2(), 'writing on file')
                          >
                          What's the difference?
                          >
                          --
                          Steven
                          Did you read the next section, "extending generic functions" ?

                          George

                          Comment

                          Working...