Using descriptors to wrap methods

Discussion in 'Python' started by Edward C. Jones, Apr 26, 2004.

  1. Here is a stripped-down version of a Python Cookbook recipe. Is there a
    simpler, more Pythonical, natural way of doing this?

    ------
    #! /usr/bin/env python

    # Modified from Python Cookbook entry 91192, "eiffelmethod" by Andres
    # Tuells. The url is
    # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/91192

    class MethodWraper(object):
    def __init__(self, method):
    self.method = method
    def __get__(self, inst, type=None):
    result = wrapper(inst, self.method)
    setattr(inst, self.method.__name__, result)
    return result

    class wrapper:
    def __init__(self, inst, method):
    self.instance = inst
    self.method = method

    def __call__(self, *args, **kargs):
    print 'pre'
    result = apply(self.method, (self.instance,) + args, kargs)
    print 'post'
    return result

    def test():
    class C:
    def f(self, arg):
    print 'in f'
    return arg+1
    f = MethodWraper(f)

    c = C()
    print c.f(1)

    if __name__=='__main__':
    test()
    ------
     
    Edward C. Jones, Apr 26, 2004
    #1
    1. Advertising

  2. Edward C. Jones

    Duncan Booth Guest

    "Edward C. Jones" <> wrote in
    news:408cfa5a$0$28920$:

    > Here is a stripped-down version of a Python Cookbook recipe. Is there a
    > simpler, more Pythonical, natural way of doing this?


    Here's a simpler way of doing the same thing:

    >>> def MethodWrapper(f):

    def wrapper(self, *args, **kw):
    print 'pre'
    result = f(self, *args, **kw)
    print 'post'
    return result
    return wrapper

    >>> class C(object):

    def f(self, arg):
    print 'in f'
    return arg+1
    f = MethodWrapper(f)


    >>> c = C()
    >>> print c.f(1)

    pre
    in f
    post
    2
    >>>


    Or if you want pre and post code customisable you might try:

    >>> def MethodWrapper(f, pre=None, post=None):

    def wrapper(self, *args, **kw):
    if pre: pre(self, *args, **kw)
    result = f(self, *args, **kw)
    if post: post(self, result, *args, **kw)
    return result
    return wrapper

    >>> class C(object):

    def pre_f(self, arg):
    print 'pre',arg
    def post_f(self, res, arg):
    print 'post',res,arg
    def f(self, arg):
    print 'in f'
    return arg+1
    f = MethodWrapper(f, pre_f, post_f)



    >>> c = C()
    >>> c.f(1)

    pre 1
    in f
    post 2 1
    2
    >>>


    I don't know if you could call it Pythonic though.
     
    Duncan Booth, Apr 26, 2004
    #2
    1. Advertising

  3. Edward C. Jones

    Sean Ross Guest

    "Edward C. Jones" <> wrote in message
    news:408cfa5a$0$28920$...
    > Here is a stripped-down version of a Python Cookbook recipe. Is there a
    > simpler, more Pythonical, natural way of doing this?
    >


    def wrap(f):
    def wrapped(*args, **kwds):
    print 'pre'
    result = f(*args, **kwds)
    print 'post'
    return result
    return wrapped
     
    Sean Ross, Apr 26, 2004
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Grant Edwards

    How to wrap a class's methods?

    Grant Edwards, Feb 17, 2005, in forum: Python
    Replies:
    14
    Views:
    540
    Steven Bethard
    Feb 20, 2005
  2. Aaron Fude

    To wrap or not to wrap?

    Aaron Fude, May 8, 2008, in forum: Java
    Replies:
    12
    Views:
    718
    Chronic Philharmonic
    May 10, 2008
  3. Kenneth McDonald
    Replies:
    5
    Views:
    345
    Kenneth McDonald
    Sep 26, 2008
  4. Art Werschulz

    Text::Wrap::wrap difference

    Art Werschulz, Sep 22, 2003, in forum: Perl Misc
    Replies:
    0
    Views:
    254
    Art Werschulz
    Sep 22, 2003
  5. Art Werschulz

    Text::Wrap::wrap difference

    Art Werschulz, Sep 24, 2003, in forum: Perl Misc
    Replies:
    1
    Views:
    257
    Anno Siegel
    Sep 25, 2003
Loading...

Share This Page