execute a function before and after any method of a parent class

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

    execute a function before and after any method of a parent class

    Hi everybody,

    I would like to be able to specialize an existing class A, so as to obtain a
    class B(A), with all methods of B being the methods of A preceded by a
    special method of B called _before_any_met hod_of_A( self ), and followed by
    a special method of B called _after_any_meth od_of_A( self ).

    The goal is to avoid to redefine explicitly in B all methods of A.

    Is this possible in Python?

    Thanks a lot

    Julien

    --
    python -c "print ''.join([chr(154 - ord(c)) for c in '*9(9&(18%.9&1+ ,\'Z
    (55l4('])"

    "When a distinguished but elderly scientist states that something is
    possible, he is almost certainly right. When he states that something is
    impossible, he is very probably wrong." (first law of AC Clarke)
  • Aaron \Castironpi\ Brady

    #2
    Re: execute a function before and after any method of a parent class

    On Oct 3, 9:03 am, TP <Tribulati...@P aralleles.inval idwrote:
    Hi everybody,
    >
    I would like to be able to specialize an existing class A, so as to obtain a
    class B(A), with all methods of B being the methods of A preceded by a
    special method of B called _before_any_met hod_of_A( self ), and followed by
    a special method of B called _after_any_meth od_of_A( self ).
    >
    The goal is to avoid to redefine explicitly in B all methods of A.
    >
    Is this possible in Python?
    >
    Thanks a lot
    >
    Julien
    >
    --
    python -c "print ''.join([chr(154 - ord(c)) for c in '*9(9&(18%.9&1+ ,\'Z
    (55l4('])"
    >
    "When a distinguished but elderly scientist states that something is
    possible, he is almost certainly right. When he states that something is
    impossible, he is very probably wrong." (first law of AC Clarke)
    Yes it's possible. The exact solution depends on how much control you
    want, and over what. Do you want inheritance or delegation? Do you
    want the same pre and post method for all inherited methods? Will you
    always use single-inheritance? Would you mind using a list of names,
    as a sort of midpoint between complete redefinition and completely
    dynamic? Do you want class lookups to succeed? If so, what do you
    want them to do?

    Generally, you could build the class dynamically with a metaclass, or
    use __getattr__ a lookup.

    Comment

    • Gabriel Genellina

      #3
      Re: execute a function before and after any method of a parent class

      En Fri, 03 Oct 2008 11:03:22 -0300, TP <Tribulations@p aralleles.inval id>
      escribió:
      I would like to be able to specialize an existing class A, so as to
      obtain a
      class B(A), with all methods of B being the methods of A preceded by a
      special method of B called _before_any_met hod_of_A( self ), and followed
      by
      a special method of B called _after_any_meth od_of_A( self ).
      >
      The goal is to avoid to redefine explicitly in B all methods of A.
      >
      Is this possible in Python?
      Sure. After reading this (excelent!) article by M. Simionato
      http://www.phyast.pitt.edu/~micheles...mentation.html you should
      be able to write a decorator to make any method into a "sandwich"
      (probably based on his "trace" example). Your code would look like this:

      @decorator
      def sandwich(f, self, *args, **kw):
      self.before()
      f(self, *args, **kw)
      self.after()

      class A:
      @sandwich
      def foo(self):
      ...

      @sandwich
      def bar(self, x):
      ...

      Ok, but then you have to explicitely decorate every method. To avoid this,
      you may use a metaclass; this article by Michael Foord explains how:


      That's all!

      --
      Gabriel Genellina

      Comment

      • Terry Reedy

        #4
        Re: execute a function before and after any method of a parent class

        Gabriel Genellina wrote:
        En Fri, 03 Oct 2008 11:03:22 -0300, TP <Tribulations@p aralleles.inval id>
        escribió:
        >
        >I would like to be able to specialize an existing class A, so as to
        >obtain a
        >class B(A), with all methods of B being the methods of A preceded by a
        >special method of B called _before_any_met hod_of_A( self ), and
        >followed by
        >a special method of B called _after_any_meth od_of_A( self ).
        >>
        >The goal is to avoid to redefine explicitly in B all methods of A.
        >>
        >Is this possible in Python?
        >
        Sure. After reading this (excelent!) article by M. Simionato
        http://www.phyast.pitt.edu/~micheles...mentation.html you
        should be able to write a decorator to make any method into a "sandwich"
        (probably based on his "trace" example). Your code would look like this:
        >
        @decorator
        def sandwich(f, self, *args, **kw):
        self.before()
        f(self, *args, **kw)
        self.after()
        >
        class A:
        @sandwich
        def foo(self):
        ...
        >
        @sandwich
        def bar(self, x):
        ...
        >
        Ok, but then you have to explicitely decorate every method. To avoid
        this, you may use a metaclass; this article by Michael Foord explains how:
        http://www.voidspace.org.uk/python/a...ting-metaclass
        I believe this would work (untested, 3.0):

        class A(): # define methods

        class B(): pass
        func = type(lambda:Non e)
        for item in A.__dict__:
        if isinstance(item , func):
        setattr(B, item.__name__, sandwich(item))

        tjr

        Comment

        • Steven D'Aprano

          #5
          Re: execute a function before and after any method of a parentclass

          On Fri, 03 Oct 2008 16:03:22 +0200, TP wrote:
          Hi everybody,
          >
          I would like to be able to specialize an existing class A, so as to
          obtain a class B(A), with all methods of B being the methods of A
          preceded by a special method of B called _before_any_met hod_of_A( self
          ), and followed by a special method of B called _after_any_meth od_of_A(
          self ).
          >
          The goal is to avoid to redefine explicitly in B all methods of A.
          >
          Is this possible in Python?
          You may be able to adapt this code to do what you are after:






          --
          Steven

          Comment

          Working...