Wrapping a method twice

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

    Wrapping a method twice

    Hi all,
    given the following code:

    ---
    def append(method,b ottom):
    def wrapped(*args, **kwargs):
    res = method(*args, **kwargs)
    return bottom(res,*arg s, **kwargs)
    setattr(method. im_class,method .__name__,wrapp ed)

    def prepend(method, top):
    def wrapped(*args, **kwargs):
    top(*args, **kwargs)
    return method(*args, **kwargs)
    setattr(method. im_class,method .__name__,wrapp ed)


    def test():
    class C:
    def f(self):
    print "f"

    def pre(self):
    print "pre"

    def post(res,self):
    print "post"

    prepend(C.f,pre )
    append(C.f,post )
    C().f()
    ---

    how comes that test() only outputs:

    pre
    f

    rather than what I expected:

    pre
    f
    post

    Thanks very much in advance,
    cheers,
    Nicolas
  • marek.rocki@wp.pl

    #2
    Re: Wrapping a method twice

    Nicolas Girard napisa³(a):
    prepend(C.f,pre )
    This wraps f, returns wrapped and binds it to C.f (but the
    method.__name__ is still wrapped).
    append(C.f,post )
    This wraps wrapped (the one previously returned), returns wrapped (a
    new one) and binds it to C.wrapped (since that is what its
    method.__name__ says).
    C().f()
    If you try C().wrapped() it works as expected.

    So the problem is in retaining the function name. Try:

    def append(method,b ottom):
    def wrapped(*args, **kwargs):
    res = method(*args, **kwargs)
    return bottom(res,*arg s, **kwargs)
    wrapped.__name_ _ = method.__name__
    setattr(method. im_class,method .__name__,wrapp ed)

    def prepend(method, top):
    def wrapped(*args, **kwargs):
    top(*args, **kwargs)
    return method(*args, **kwargs)
    wrapped.__name_ _ = method.__name__
    setattr(method. im_class,method .__name__,wrapp ed)

    Comment

    • Michele Simionato

      #3
      Re: Wrapping a method twice

      On Jun 25, 1:52 pm, marek.ro...@wp. pl wrote:
      >Try:
      >
      def append(method,b ottom):
          def wrapped(*args, **kwargs):
              res = method(*args, **kwargs)
              return bottom(res,*arg s, **kwargs)
          wrapped.__name_ _ = method.__name__
          setattr(method. im_class,method .__name__,wrapp ed)
      >
      def prepend(method, top):
          def wrapped(*args, **kwargs):
              top(*args, **kwargs)
              return method(*args, **kwargs)
          wrapped.__name_ _ = method.__name__
          setattr(method. im_class,method .__name__,wrapp ed)
      If you are using Python 2.5, consider functools.updat e_wrapper, which
      also sets __module__,
      __doc__ and other attributes.

      Comment

      Working...