bend or redirect a class method and then call it again

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

    bend or redirect a class method and then call it again

    Hello,

    (in wxPython)

    I want to redirect the SetStatusText
    to an own method (change the text somewhat) and
    then call the SetStatusText of wx.Frame.

    But I have a little problem of understanding, but I think,
    it should be achieved somehow.

    the output of "show_statu s" should be then:
    "mytext: hallo"

    class MyFrame (wx.Frame):
    def show_status(sel f):
    SetStatusText ("hallo")

    my_frame = Myframe

    Plugin (my_frame)

    def Plugin(frame_in st)

    #here i want to redirect the setstatustext

    setattr(frame_i nst, 'SetStatusText' , NewStatusText)

    def SetStatusText(t e,text,nr=0):
    super(MyFrame, MyFrame).SetSta tusText("mytext : " + te)
    #this is erronous

    def NewStatusText(s , n, n1= 0):
    SetStatusText(s , n, n1)

    Is this possible?
    How can I get this working?

    thank you in advance
    --
    Franz Steinhaeusler
  • Scott David Daniels

    #2
    Re: bend or redirect a class method and then call it again

    Franz Steinhaeusler wrote:
    [color=blue]
    > I want to redirect the SetStatusText
    > to an own method (change the text somewhat) and
    > then call the SetStatusText of wx.Frame.[/color]

    You are being a bit informal with what is a method and what is a
    function. Your examples don't even parse. I think this informality
    may be the source of your problem.
    [color=blue]
    > class MyFrame (wx.Frame):
    > def show_status(sel f):
    > SetStatusText ("hallo")
    > my_frame = Myframe[/color]
    perhaps you mean:
    my_frame = Myframe()[color=blue]
    > Plugin (my_frame)[/color]
    [color=blue]
    > def Plugin(frame_in st)[/color]
    No colon above
    [color=blue]
    > #here i want to redirect the setstatustext
    > setattr(frame_i nst, 'SetStatusText' , NewStatusText)[/color]
    You seem to be trying to create a subclass dynamically.
    [color=blue]
    > def SetStatusText(t e,text,nr=0):
    > super(MyFrame, MyFrame).SetSta tusText("mytext : " + te)
    > #this is erronous[/color]
    The super call is being done inside a function, not a class.
    [color=blue]
    >
    >
    > Is this possible?
    > How can I get this working?[/color]

    Does this address your problem?:

    class MyFrame(wx.Fram e):
    def show_status(sel f):
    SetStatusText(" hallo")

    def SetStatusText(s elf, te, text, nr=0):
    super(MyFrame, self).SetStatus Text("mytext: " + te)

    -Scott David Daniels
    Scott.Daniels@A cm.Org

    Comment

    • Franz Steinhaeusler

      #3
      Re: bend or redirect a class method and then call it again

      On Wed, 21 Jul 2004 12:21:33 -0700, Scott David Daniels
      <Scott.Daniels@ Acm.Org> wrote:
      [color=blue]
      >[...]
      >Does this address your problem?:
      >
      > class MyFrame(wx.Fram e):
      > def show_status(sel f):
      > SetStatusText(" hallo")
      >
      > def SetStatusText(s elf, te, text, nr=0):
      > super(MyFrame, self).SetStatus Text("mytext: " + te)
      >[/color]

      thank you,

      I was not exact enough.

      It was not so easy, because I had to apply the super in a function
      and not in the class itself.

      but finally i got it to work:

      #drFrame is inherited from wx.Frame
      #in drFrame there are some calls to SetStatusText



      import wx
      from drpython import DrFrame

      def Plugin(DrFrame) :

      def SetStatusText(t ext, col):
      if col == 1:
      #text.find
      ind1 = text.find ("Col: ")
      if ind1 > -1:
      ind1 += len ("Col: ");
      ind2 = text.find (" ", ind1)
      nr = int (text [ind1:ind2]) + 1
      text = text [:ind1] + str (nr) + text[ind2:]
      super(type(DrFr ame), DrFrame).SetSta tusText(text, col)

      def NewStatusText(t ext, col=0):
      SetStatusText(t ext, col)

      setattr(DrFrame , 'SetStatusText' , NewStatusText)


      Is there a better/simpler/clearer solution?

      thank you
      --
      Franz Steinhaeusler

      Comment

      • Jeff Shannon

        #4
        Re: bend or redirect a class method and then call it again

        Franz Steinhaeusler wrote:
        [color=blue]
        >#drFrame is inherited from wx.Frame
        >#in drFrame there are some calls to SetStatusText
        >
        >import wx
        >from drpython import DrFrame
        >
        >def Plugin(DrFrame) :
        >
        > def SetStatusText(t ext, col):
        > #[...]
        >
        > def NewStatusText(t ext, col=0):
        > SetStatusText(t ext, col)
        >
        > setattr(DrFrame , 'SetStatusText' , NewStatusText)
        >
        >[/color]


        What's the point of this extra 'NewStatusText' method? You're already
        overriding SetStatusText. Without the NewStatusText and the setattr()
        call, when someone calls SomePluginObjec t.SetStatusText (), it will call
        your new version rather than the wx.Frame (or DrFrame) version -- that's
        the whole point of inheritance. (This is true even when the 'someone'
        is the object itself, from within the DrFrame base class. The *only*
        way to get the base class version(s) is by explicitly asking for it.)
        The extra method and setattr() don't seem to be gaining you anything.

        Jeff Shannon
        Technician/Programmer
        Credit International

        Comment

        • Francesco

          #5
          Re: bend or redirect a class method and then call it again

          On Thu, 22 Jul 2004 10:58:33 -0700, Jeff Shannon <jeff@ccvcorp.c om>
          wrote:
          [color=blue][color=green]
          >>[#drFrame is inherited from wx.Frame]
          >>[#in drFrame there are some calls to SetStatusText][/color][/color]

          I think, I don't make it clear enough.

          in drFrame there are some calls to SetStatusText.
          these, I want catch, change some strings, and send it back;
          simply said.
          [color=blue]
          >What's the point of this extra 'NewStatusText' method? You're already
          >overriding SetStatusText. Without the NewStatusText and the setattr()
          >call, when someone calls SomePluginObjec t.SetStatusText (), it will call
          >your new version rather than the wx.Frame (or DrFrame) version[/color]


          but not from drFrame itself; that is the point.

          I want:
          ALL the calls SetStatusText IN DRFRAME itself should be processed.
          [color=blue]
          >-- that's
          >the whole point of inheritance. (This is true even when the 'someone'
          >is the object itself, from within the DrFrame base class. The *only*
          >way to get the base class version(s) is by explicitly asking for it.)
          >The extra method and setattr() don't seem to be gaining you anything.[/color]

          these calls (in drFrame), I want to "trick", to go further down one
          level, or better said redirect to my own function, change the text,
          and use the normal SetStatusText from wx.Frame.


          Anyway, thank you.
          --
          Francesco

          Comment

          • Jeff Shannon

            #6
            Re: bend or redirect a class method and then call it again

            Francesco wrote:
            [color=blue][color=green]
            >>What's the point of this extra 'NewStatusText' method? You're already
            >>overriding SetStatusText. Without the NewStatusText and the setattr()
            >>call, when someone calls SomePluginObjec t.SetStatusText (), it will call
            >>your new version rather than the wx.Frame (or DrFrame) version
            >>
            >>[/color]
            >
            >but not from drFrame itself; that is the point.
            >
            >[/color]

            Unless I'm misunderstandin g your intent, then yes, from drFrame itself.

            Every Plugin object is also a drFrame object (and a wx.Frame object).
            *Every* SetStatusText() call on any such object will use the
            most-derived version of SetStatusText() , i.e. the Plugin version. Even
            the calls that are part of the drFrame class definition. The *only*
            exception to this is if, instead of using self.SetStatusT ext(), you're
            using drFrame.SetStat usText(self, ...) -- in that case, you've
            explicitly asked for the drFrame version. But if you have, for example,
            something like this:

            class drFrame(wx.Fram e):
            def do_something(se lf, *args):
            # [....]
            self.SetStatusT ext("New Status")

            then despite the fact that this is a drFrame method, and doesn't know
            anything about the Plugin derived class, it will indeed result in the
            Plugin version of SetStatusText() being called. That's the whole
            *point* of inheritance.

            I can see two cases where what you're doing would have some effect that
            doesn't replicate normal method resolution order, and to be honest I
            think that using either case is a sign of some very questionable design
            decisions and definitely violates the guiding principles of OO and
            inheritance. One case would be that there are indeed places where the
            drFrame.SetStat usText(self, ...) is explicitly called, and you're trying
            to override those explicit requests. This is bad form -- an explicit
            request should be honored, because there's probably a real reason for
            it. The other case is where you are trying to modify the behavior of
            all drFrame instances, including those which are *not* also Plugin
            instances.

            In both cases, you're doing something magic behind your back. It's much
            better to do that kind of stuff up front, where it can be seen. (For
            instance, in the second case, simply derive an intermediate class from
            drFrame, and then derive Plugin from that. Use the intermediate class
            anywhere where you'd currently use drFrame, and you're set.) I would
            bet that there's a more straightforward way of accomplishing what you
            actually want to do, without resorting to this kind of sleight-of-hand.
            (I trust sleight-of-hand in programs about as much as I trust
            sleight-of-hand in people who're holding my wallet -- there may be cases
            where it's justified and where it can be trusted, but I'm not going to
            hand my wallet to just anyone...)

            Jeff Shannon
            Technician/Programmer
            Credit International

            Comment

            • Franz Steinhaeusler

              #7
              Re: bend or redirect a class method and then call it again

              On Thu, 22 Jul 2004 14:24:28 -0700, Jeff Shannon <jeff@ccvcorp.c om>
              wrote:

              Hello Jeff,
              [color=blue]
              >Francesco wrote:
              >[color=green][color=darkred]
              >>>What's the point of this extra 'NewStatusText' method? You're already
              >>>overriding SetStatusText. Without the NewStatusText and the setattr()
              >>>call, when someone calls SomePluginObjec t.SetStatusText (), it will call
              >>>your new version rather than the wx.Frame (or DrFrame) version
              >>>
              >>>[/color]
              >>
              >>but not from drFrame itself; that is the point.
              >>
              >>[/color]
              >
              >Unless I'm misunderstandin g your intent, then yes, from drFrame itself.
              >
              >Every Plugin object is also a drFrame object (and a wx.Frame object).[/color]

              No. Plugin is a *function*, which receives a *drFrame object*.
              It should have the purpose to "redirect" all the SetStatusText
              calls from within drFrame.
              [color=blue]
              >*Every* SetStatusText() call on any such object will use the
              >most-derived version of SetStatusText() , i.e. the Plugin version. Even
              >the calls that are part of the drFrame class definition. The *only*
              >exception to this is if, instead of using self.SetStatusT ext(), you're
              >using drFrame.SetStat usText(self, ...) -- in that case, you've
              >explicitly asked for the drFrame version. But if you have, for example,
              >something like this:
              >
              >class drFrame(wx.Fram e):
              > def do_something(se lf, *args):
              > # [....]
              > self.SetStatusT ext("New Status")
              >
              >then despite the fact that this is a drFrame method, and doesn't know
              >anything about the Plugin derived class, it will indeed result in the
              >Plugin version of SetStatusText() being called. That's the whole
              >*point* of inheritance.[/color]

              I see.
              [color=blue]
              >
              >I can see two cases where what you're doing would have some effect that
              >doesn't replicate normal method resolution order, and to be honest I
              >think that using either case is a sign of some very questionable design
              >decisions and definitely violates the guiding principles of OO and
              >inheritance. One case would be that there are indeed places where the
              >drFrame.SetSta tusText(self, ...) is explicitly called, and you're trying
              >to override those explicit requests. This is bad form -- an explicit
              >request should be honored, because there's probably a real reason for
              >it. The other case is where you are trying to modify the behavior of
              >all drFrame instances, including those which are *not* also Plugin
              >instances.[/color]

              This I want to achieve.

              I betted, that there comes the question of bad design :)
              [color=blue]
              >
              >In both cases, you're doing something magic behind your back. It's much
              >better to do that kind of stuff up front, where it can be seen. (For
              >instance, in the second case, simply derive an intermediate class from
              >drFrame, and then derive Plugin from that. Use the intermediate class
              >anywhere where you'd currently use drFrame, and you're set.) I would
              >bet that there's a more straightforward way of accomplishing what you
              >actually want to do, without resorting to this kind of sleight-of-hand.
              >(I trust sleight-of-hand in programs about as much as I trust
              >sleight-of-hand in people who're holding my wallet -- there may be cases
              >where it's justified and where it can be trusted, but I'm not going to
              >hand my wallet to just anyone...)[/color]

              Thank you for your extensive explanation and for the tips.

              I will think about it again.


              --
              Franz Steinhaeusler

              Comment

              • Jeff Shannon

                #8
                Re: bend or redirect a class method and then call it again

                Franz Steinhaeusler wrote:
                [color=blue]
                >On Thu, 22 Jul 2004 14:24:28 -0700, Jeff Shannon <jeff@ccvcorp.c om>
                >wrote:
                >
                >
                >[color=green]
                >>Unless I'm misunderstandin g your intent, then yes, from drFrame itself.
                >>
                >>Every Plugin object is also a drFrame object (and a wx.Frame object).
                >>
                >>[/color]
                >
                >No. Plugin is a *function*, which receives a *drFrame object*.
                >It should have the purpose to "redirect" all the SetStatusText
                >calls from within drFrame.
                >
                >[/color]

                Ah, well, then I *was* misunderstandin g -- I'm not sure how I became
                convinced that Plugin was a derived class, but convinced I was, and
                built all further opinions on top of that false conviction.

                I'd say that if you want a function to alter the behavior of all objects
                of a particular class, it's probably better to have some sort of flag as
                a class variable, and have your function set that flag rather than
                rebind a method. I'd still be inclined to think that this should be
                done on a per-instance basis, rather than for the entire class, but I
                can see some case to be made for changing the entire class, too.

                Perhaps you can define a StatusTextForma t attribute on drFrame, and have
                drFrame.SetStat usText() apply that format to all text before feeding it
                to wx.Frame.SetSta tusText(). Plugin() would then change this
                StatusTextForma t. You could implement this as either a function to be
                called, or use % string formatting...

                Jeff Shannon
                Technician/Programmer
                Credit International

                Comment

                • Francesco

                  #9
                  Re: bend or redirect a class method and then call it again

                  On Fri, 23 Jul 2004 13:45:07 -0700, Jeff Shannon <jeff@ccvcorp.c om>
                  wrote:
                  [color=blue]
                  >Ah, well, then I *was* misunderstandin g -- I'm not sure how I became
                  >convinced that Plugin was a derived class, but convinced I was, and
                  >built all further opinions on top of that false conviction.
                  >
                  >I'd say that if you want a function to alter the behavior of all objects
                  >of a particular class, it's probably better to have some sort of flag as
                  >a class variable, and have your function set that flag rather than
                  >rebind a method. I'd still be inclined to think that this should be
                  >done on a per-instance basis, rather than for the entire class, but I
                  >can see some case to be made for changing the entire class, too.
                  >
                  >Perhaps you can define a StatusTextForma t attribute on drFrame, and have
                  >drFrame.SetSta tusText() apply that format to all text before feeding it
                  >to wx.Frame.SetSta tusText(). Plugin() would then change this
                  >StatusTextForm at. You could implement this as either a function to be
                  >called, or use % string formatting...[/color]


                  thank you again for your answer.
                  I have to think about it.

                  --
                  Franz Steinhaeusler

                  Comment

                  Working...