extending methods ?

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

    extending methods ?

    Hi,

    the summary of my question is:
    is there a way to append commands to a method inherited from
    another class?

    More verbose: Assume the following situation that I have
    a class class_A with several methods.
    In each of these methods quite a few computations take place
    and several variables are defined.
    Now I would like to extend this class to a class_B.
    However, instead of overriding a method completely,
    I would like to extend the method by basically adding
    further commands at the end.

    Eg., the code could look like:

    class class_A:
    def method1(self,x) :
    y=5*x+1 # create a variable


    class class_B(class_A ):
    appendto method1(self,x) :
    print y # use variable defined in class_A


    I.e. Effictively class_B should "look" like:

    class class_B(class_A ):
    def method1(self,x) :
    y=5*x+1 # create a variable
    print y # use the variable

    Instead of this, one could in principle
    store all variables defined in
    method1 of class_A, eg. with self.y=y
    and call in class_B the method1 of class_A.
    However, with several variables and several methods
    the code will not look nice.
    (also efficiency is a bit of concern - presumably it shouldn't -
    to me here as in my application the methods
    are used to plot dots, circles, triangles etc.
    so that speed is really important)

    So is there a way to extend methods in the above sense
    or is there a better (more pythonic ? ;-) approach to what I want?

    Many thanks in advance.

    Arnd

    P.S.: Sorry if I messed up things on the OO side
    (I am a real new-comer to this ...;-).


  • Alex Martelli

    #2
    Re: extending methods ?

    Arnd Baecker wrote:
    [color=blue]
    > Hi,
    >
    > the summary of my question is:
    > is there a way to append commands to a method inherited from
    > another class?[/color]

    The canonical way to achieve that is to override the method,
    and, within the override, call up to the superclass's
    implementation.

    [color=blue]
    > More verbose: Assume the following situation that I have
    > a class class_A with several methods.
    > In each of these methods quite a few computations take place
    > and several variables are defined.[/color]

    Ah, no way, then -- local variables of a method (just like
    any other function) are totally internal to that method, and
    there is absolutely no reasonable way to access them from
    the outside.
    [color=blue]
    > However, with several variables and several methods
    > the code will not look nice.[/color]

    A matter of opinion. I find it much nicer to know that a
    local variable is local, and an instance variable is not.
    [color=blue]
    > (also efficiency is a bit of concern - presumably it shouldn't -[/color]

    Right, it shouldn't. Local variables are fast BECAUSE they
    are local. If they were non-local -- as you require, in order
    to work with them from outside the defining method -- then
    they wouldn't be fast.
    [color=blue]
    > to me here as in my application the methods
    > are used to plot dots, circles, triangles etc.
    > so that speed is really important)[/color]

    I strongly doubt that the loss of speed due to making some
    needed variable non-local is going to be measurable. Taking
    your example...:

    [alex@lancelot python2.3]$ python timeit.py \[color=blue]
    > -s 'class A:' \
    > -s ' def method1(self, x): y = 5 * x + 1' \
    > -s ' def method2(self, x): self.y = 5 * x + 1' \
    > -s 'a=A()' \
    > 'a.method1(23)'[/color]
    1000000 loops, best of 3: 1.47 usec per loop

    and the same with method2 instead: 1.66 usec per loop.

    What makes you think that a "slow-down" of 190 nanoseconds,
    i.e. about 13% on this method call, is gonna be SO crucial?

    And if you ARE working in an environment where every single
    nanosecond matter, then what about...:

    [alex@lancelot python2.3]$ python timeit.py \[color=blue]
    > -s 'class A:' \
    > -s ' def method1(self, x): y = 5 * x + 1' \
    > -s ' def method2(self, x): self.y = 5 * x + 1' \
    > -s 'a=A()' \[/color]
    - -s 'meth=a.method2 ' \[color=blue]
    > 'meth(23)'[/color]
    1000000 loops, best of 3: 1.25 usec per loop

    See? Extracting the bound method once and for all saves
    you a whopping *410* nanoseconds per call, compensating
    the 190 "lost" by making instance variables where you need
    them *and then some*. In other words, there are ways and
    means to squeeze nanoseconds out of some Python bottleneck
    that do not necessarily require using local variables where
    you need instance or other non-local ones!

    [color=blue]
    > So is there a way to extend methods in the above sense
    > or is there a better (more pythonic ? ;-) approach to what I want?[/color]

    There is no pythonic way to treat local variables as non-local.
    (There MAY be horrible bytecode hacks exploiting hooks that are
    meant for debugging only -- but THOSE *WILL* slow you down
    SERIOUSLY...).


    Alex

    Comment

    • David C. Fox

      #3
      Re: extending methods ?

      Arnd Baecker wrote:[color=blue]
      > Hi,
      >
      > the summary of my question is:
      > is there a way to append commands to a method inherited from
      > another class?
      >
      > More verbose: Assume the following situation that I have
      > a class class_A with several methods.
      > In each of these methods quite a few computations take place
      > and several variables are defined.
      > Now I would like to extend this class to a class_B.
      > However, instead of overriding a method completely,
      > I would like to extend the method by basically adding
      > further commands at the end.
      >
      > Eg., the code could look like:
      >
      > class class_A:
      > def method1(self,x) :
      > y=5*x+1 # create a variable
      >
      >
      > class class_B(class_A ):
      > appendto method1(self,x) :
      > print y # use variable defined in class_A
      >
      >
      > I.e. Effictively class_B should "look" like:
      >
      > class class_B(class_A ):
      > def method1(self,x) :
      > y=5*x+1 # create a variable
      > print y # use the variable
      >[/color]

      If you really want to do this, you are probably better off doing it
      explicitly. For example


      class A:
      def store_locals(se lf, local_variables , keep_locals):
      if keep_locals is None:
      return
      keep_locals.upd ate(local_varia bles)

      def m(self, x, keep_locals = None):
      """If you want to keep the local variables of this method,
      specify a dictionary for keep_locals
      """
      y = 5*x+1
      self.store_loca ls(locals(), keep_locals)


      class C(A):
      def m(self, x, keep_locals = None):
      if keep_locals is None:
      keep_locals = {}
      v = A.m(self, x, keep_locals = keep_locals)
      print 'y was ', keep_locals['y']
      return v

      [color=blue]
      > P.S.: Sorry if I messed up things on the OO side
      > (I am a real new-comer to this ...;-).[/color]

      Perhaps if you tell us more about why you want to do this, we could come
      up with a better OO solution.

      David

      Comment

      • David Eppstein

        #4
        Re: extending methods ?

        In article <HyBeb.645796$Y N5.495743@sccrn sc01>,
        "David C. Fox" <davidcfox@post .harvard.edu> wrote:
        [color=blue]
        > Perhaps if you tell us more about why you want to do this, we could come
        > up with a better OO solution.[/color]

        Actually this seems exactly the sort of thing for which aspect oriented
        programming was developed.


        seems to find a few relevant pages...

        --
        David Eppstein http://www.ics.uci.edu/~eppstein/
        Univ. of California, Irvine, School of Information & Computer Science

        Comment

        • Stephen Horne

          #5
          Re: extending methods ?

          On Wed, 1 Oct 2003 09:45:45 +0200 (CEST), Arnd Baecker
          <arnd.baecker@w eb.de> wrote:
          [color=blue]
          >the summary of my question is:
          >is there a way to append commands to a method inherited from
          >another class?[/color]

          If you can call...

          instance.method (arg1, ...)

          then you can equivalently call...

          classname.metho d (instance, arg1, ...)

          You can use this in your subclasses method to call the method from a
          specified base class (with multiple inheritance there may be more than
          one base). For example...
          [color=blue][color=green][color=darkred]
          >>> class A (object) :[/color][/color][/color]
          .... def dostuff (self) :
          .... print "running A.dostuff"
          ....[color=blue][color=green][color=darkred]
          >>> class B (A) :[/color][/color][/color]
          .... def dostuff (self) :
          .... print "running B.dostuff"
          .... A.dostuff (self)
          ....[color=blue][color=green][color=darkred]
          >>> b=B()
          >>> b.dostuff()[/color][/color][/color]
          running B.dostuff
          running A.dostuff


          --
          Steve Horne

          steve at ninereeds dot fsnet dot co dot uk

          Comment

          • Carlo v. Dango

            #6
            Re: extending methods ?

            David Eppstein <eppstein@ics.u ci.edu> wrote in
            news:eppstein-A4BD3C.10271901 102003@news.ser vice.uci.edu:
            [color=blue]
            > In article <HyBeb.645796$Y N5.495743@sccrn sc01>,
            > "David C. Fox" <davidcfox@post .harvard.edu> wrote:
            >[color=green]
            >> Perhaps if you tell us more about why you want to do this, we could
            >> come up with a better OO solution.[/color]
            >
            > Actually this seems exactly the sort of thing for which aspect
            > oriented programming was developed.[/color]

            excuse me, but that is utterly and completely rubbish! :-) Specializing
            methods is actually very useful, but I've only seen it in the language
            Beta (well I'm certain it could be achieved in Simula 67 as well). In
            simula classes and methods has been unified into the notion of a
            "pattern". So since you can specialize classes, you now also can
            specialize methods using this pattern construct.

            AOP was designed to be able to define CROSS-CUTTING entities crosscutting
            at least 2 inheritance hierachies.

            You should all at least try to read up on the Beta language and grasp its
            powerful idea of the pattern construct!

            -carlo van dango

            Comment

            Working...