grandparent method with super

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

    grandparent method with super

    Hi,

    I have a class structure as follows and I would like to invoke the
    method A.m() from D.m

    class A(object):
    def m(self):
    class B(A):
    def m(self):
    class C(A):
    def m(self):
    class D(B,C):
    def m(self):
    # Call A.m with super?

    I have read http://www.python.org/download/releases/2.2/descrintro/ but
    I am still stuck.

    Thanks in advance

    Martin
  • kyosohma@gmail.com

    #2
    Re: grandparent method with super

    On Apr 5, 3:19 pm, Martin Manns <mma...@gmx.dew rote:
    Hi,
    >
    I have a class structure as follows and I would like to invoke the
    method A.m() from D.m
    >
    class A(object):
    def m(self):
    class B(A):
    def m(self):
    class C(A):
    def m(self):
    class D(B,C):
    def m(self):
    # Call A.m with super?
    >
    I have readhttp://www.python.org/download/releases/2.2/descrintro/but
    I am still stuck.
    >
    Thanks in advance
    >
    Martin
    I'm not sure if this is what you want, but it's my best guess:

    class A(object):
    def m(self):
    print "I'm the original"
    class B(A):
    def m(self):
    print 'B class here'
    class C(A):
    def m(self):
    print 'C class here'
    class D(B,C):
    def m(self):
    x = A()
    x.m()

    temp = D()
    temp.m()



    Mike

    Comment

    • John Clark

      #3
      RE: grandparent method with super

      Pretty sure you can do this:

      class A(object):
      def m(self):
      class B(A):
      def m(self):
      class C(A):
      def m(self):
      class D(B,C):
      def m(self):
      A.m(self)

      I don't think you want to try to use super() in this case.

      -jdc

      -----Original Message-----
      From: python-list-bounces+clajo04 =mac.com@python .org
      [mailto:python-list-bounces+clajo04 =mac.com@python .org] On Behalf Of Martin
      Manns
      Sent: Thursday, April 05, 2007 4:20 PM
      To: python-list@python.org
      Subject: grandparent method with super

      Hi,

      I have a class structure as follows and I would like to invoke the method
      A.m() from D.m

      class A(object):
      def m(self):
      class B(A):
      def m(self):
      class C(A):
      def m(self):
      class D(B,C):
      def m(self):
      # Call A.m with super?

      I have read http://www.python.org/download/releases/2.2/descrintro/ but I am
      still stuck.

      Thanks in advance

      Martin
      --


      Comment

      • Martin Manns

        #4
        Re: grandparent method with super

        On Thu, 5 Apr 2007 16:33:37 -0400
        "John Clark" <clajo04@mac.co mwrote:
        Pretty sure you can do this:
        >
        class A(object):
        def m(self):
        class B(A):
        def m(self):
        class C(A):
        def m(self):
        class D(B,C):
        def m(self):
        A.m(self)
        >
        I don't think you want to try to use super() in this case.
        That works, but when I replace A with something else, I do not get the
        grandparent anymore without changing all the method calls. Basically, I
        would like to call the method m in the first grandparent of D.

        Martin

        Comment

        • John Clark

          #5
          RE: grandparent method with super

          >Pretty sure you can do this:
          >>
          >class A(object):
          > def m(self):
          >class B(A):
          > def m(self):
          >class C(A):
          > def m(self):
          >class D(B,C):
          > def m(self):
          > A.m(self)
          >>
          >I don't think you want to try to use super() in this case.
          >
          >That works, but when I replace A with something else, I do not get the
          grandparent anymore
          >without changing all the method calls. Basically, I would like to call the
          method m in the first
          >grandparent of D.
          >
          >Martin
          I think the problem you may run into is with the term "first grandparent" -
          when you look at the method resolution order of the class D, you will find
          that the MRO goes "D, C, B, A"... I think it's going to be difficult to
          figure out where the "first grandparent" is in the MRO.

          For example:

          class A(object):
          def m(self):
          pass
          class B(A):
          def m(self):
          pass
          class C(B):
          def m(self):
          pass
          class D(A):
          def m(self):
          pass
          class E(C,D):
          def m(self):
          firstgrandparen t(E,self).m() #Should call B.m
          class F(D,C):
          def m(self):
          firstgrandparen t(F,self).m() # Should call F.m


          The mro for class E is going to be "E,C,B,D,A" where as the mro for class F
          is going to be "F,D,C,B,A" . However, the first grandparent for E should be
          B, where as the first grandparent for F should be A.

          Because the MRO isn't just a depth first traversal, the term "first
          grandparent" gets tricky to define...

          -jdc


          --


          Comment

          • Martin Manns

            #6
            Re: grandparent method with super

            On Thu, 5 Apr 2007 16:55:38 -0400
            "John Clark" <clajo04@mac.co mwrote:
            That works, but when I replace A with something else, I do not get
            the
            grandparent anymore
            without changing all the method calls. Basically, I would like to
            call the
            method m in the first
            grandparent of D.

            Martin
            >
            I think the problem you may run into is with the term "first
            grandparent" - when you look at the method resolution order of the
            class D, you will find that the MRO goes "D, C, B, A"... I think it's
            going to be difficult to figure out where the "first grandparent" is
            in the MRO.
            >
            For example:
            >
            class A(object):
            def m(self):
            pass
            class B(A):
            def m(self):
            pass
            class C(B):
            def m(self):
            pass
            class D(A):
            def m(self):
            pass
            class E(C,D):
            def m(self):
            firstgrandparen t(E,self).m() #Should call B.m
            class F(D,C):
            def m(self):
            firstgrandparen t(F,self).m() # Should call F.m
            >
            >
            The mro for class E is going to be "E,C,B,D,A" where as the mro for
            class F is going to be "F,D,C,B,A" . However, the first grandparent
            for E should be B, where as the first grandparent for F should be A.
            >
            Because the MRO isn't just a depth first traversal, the term "first
            grandparent" gets tricky to define...
            Not really. The first grandparent would be the first occurrence in the
            list from left to right, which satisfies the requirement that its
            shortest path to the current class is 2.

            The only problem: How do I get it?

            Martin

            Comment

            • Gabriel Genellina

              #7
              Re: grandparent method with super

              En Thu, 05 Apr 2007 18:13:06 -0300, Martin Manns <mmanns@gmx.dee scribió:
              On Thu, 5 Apr 2007 16:55:38 -0400
              "John Clark" <clajo04@mac.co mwrote:
              >Because the MRO isn't just a depth first traversal, the term "first
              >grandparent" gets tricky to define...
              >
              Not really. The first grandparent would be the first occurrence in the
              list from left to right, which satisfies the requirement that its
              shortest path to the current class is 2.
              The only problem: How do I get it?
              Calling super() twice? F.mro()[1]? But really I don't think it's a good
              idea - depending on the *other* classes in your hierarchy, what you call
              "grandparen t" may be almost anyone.
              If you *have* to bypass your parent, it feels like there is something
              wrong in the class hierarchy.

              --
              Gabriel Genellina

              Comment

              • attn.steven.kuo@gmail.com

                #8
                Re: grandparent method with super

                On Apr 5, 2:13 pm, Martin Manns <mma...@gmx.dew rote:
                On Thu, 5 Apr 2007 16:55:38 -0400
                >
                >
                >
                "John Clark" <claj...@mac.co mwrote:
                >That works, but when I replace A with something else, I do not get
                >the
                grandparent anymore
                >without changing all the method calls. Basically, I would like to
                >call the
                method m in the first
                >grandparent of D.
                >
                >Martin
                >
                I think the problem you may run into is with the term "first
                grandparent" - when you look at the method resolution order of the
                class D, you will find that the MRO goes "D, C, B, A"... I think it's
                going to be difficult to figure out where the "first grandparent" is
                in the MRO.
                >
                For example:
                >
                class A(object):
                def m(self):
                pass
                class B(A):
                def m(self):
                pass
                class C(B):
                def m(self):
                pass
                class D(A):
                def m(self):
                pass
                class E(C,D):
                def m(self):
                firstgrandparen t(E,self).m() #Should call B.m
                class F(D,C):
                def m(self):
                firstgrandparen t(F,self).m() # Should call F.m
                >
                The mro for class E is going to be "E,C,B,D,A" where as the mro for
                class F is going to be "F,D,C,B,A" . However, the first grandparent
                for E should be B, where as the first grandparent for F should be A.
                >
                Because the MRO isn't just a depth first traversal, the term "first
                grandparent" gets tricky to define...
                >
                Not really. The first grandparent would be the first occurrence in the
                list from left to right, which satisfies the requirement that its
                shortest path to the current class is 2.
                >
                The only problem: How do I get it?
                >
                Martin


                class E(C,D):
                def m(self):
                for cls in E.__mro__:
                if cls != E and cls not in E.__bases__:
                cls.m(self)
                break


                .... but it's probably better that you
                rethink your class hierarchy.

                --
                Hope this helps,
                Steven

                Comment

                • John Clark

                  #9
                  RE: grandparent method with super

                  Not really. The first grandparent would be the first occurrence in the
                  list from left to right, which satisfies the requirement that its shortest
                  path to the current class is 2.
                  The only problem: How do I get it?
                  Martin
                  I suppose you could do a

                  self.__class__. __bases__[0].__bases__[0]

                  (With the appropriate error handling buit in..)

                  But I am not sure if it's a safe assumption to depend on __bases__ returning
                  the classes in the order you want...

                  -jdc


                  --


                  Comment

                  • Martin Manns

                    #10
                    Re: grandparent method with super

                    On 5 Apr 2007 15:05:25 -0700
                    attn.steven.kuo @gmail.com wrote:
                    >
                    class E(C,D):
                    def m(self):
                    for cls in E.__mro__:
                    if cls != E and cls not in E.__bases__:
                    cls.m(self)
                    break
                    >
                    >
                    ... but it's probably better that you
                    rethink your class hierarchy.
                    After seeing the implications and the solutions, I will.

                    Thank you everyone for your help

                    Martin

                    Comment

                    • Bruno Desthuilliers

                      #11
                      Re: grandparent method with super

                      kyosohma@gmail. com a écrit :
                      On Apr 5, 3:19 pm, Martin Manns <mma...@gmx.dew rote:
                      >
                      >>Hi,
                      >>
                      >>I have a class structure as follows and I would like to invoke the
                      >>method A.m() from D.m
                      >>
                      >>class A(object):
                      > def m(self):
                      >>class B(A):
                      > def m(self):
                      >>class C(A):
                      > def m(self):
                      >>class D(B,C):
                      > def m(self):
                      > # Call A.m with super?
                      >>
                      (snip)
                      I'm not sure if this is what you want, but it's my best guess:
                      >
                      class A(object):
                      def m(self):
                      print "I'm the original"
                      class B(A):
                      def m(self):
                      print 'B class here'
                      class C(A):
                      def m(self):
                      print 'C class here'
                      class D(B,C):
                      def m(self):
                      x = A()
                      x.m()
                      Err... This will call A.m(x), not A.m(self). The correct thing to is:
                      class D(B,C):
                      def m(self):
                      A.m(self)

                      But this doesn't solve the OP's problem, which is to not hard-code the
                      concrete base class to call (hence the question about how to do this
                      using super)

                      Comment

                      Working...