On Tue, Oct 11, 2011 at 12:14 PM, Toshio Kuratomi <a.bad...@gmail.com>wrote:
> This may not be the preferred manner to write decorators but it's fairly > straightforward and easy to remember compared to, say, porting away from > the > with statement. > You can emulate 'with' using decorators, actually, if you don't mind a nested function. Some code from my Contextual library (minus the tests): *def* *call_with*(ctxmgr): *"""Emulate the PEP 343 "with" statement for Python versions <2.5 The following examples do the same thing at runtime:: Python 2.5+ Python 2.4 ------------ ------------- with x as y: @call_with(x) print y def do_it(y): print y ``call_with(foo)`` returns a decorator that immediately invokes the function it decorates, passing in the same value that would be bound by the ``as`` clause of the ``with`` statement. Thus, by decorating a nested function, you can get most of the benefits of "with", at a cost of being slightly slower and perhaps a bit more obscure than the 2.5 syntax. Note: because of the way decorators work, the return value (if any) of the ``do_it()`` function above will be bound to the name ``do_it``. So, this example prints "42":: @call_with(x) def do_it(y): return 42 print do_it This is rather ugly, so you may prefer to do it this way instead, which more explicitly calls the function and gets back a value:: def do_it(y): return 42 print with_(x, do_it) """* *return* with_.__get__(ctxmgr, type(ctxmgr)) *def* *with_*(ctx, func): *"""Perform PEP 343 "with" logic for Python versions <2.5 The following examples do the same thing at runtime:: Python 2.5+ Python 2.3/2.4 ------------ -------------- with x as y: z = with_(x,f) z = f(y) This function is used to implement the ``call_with()`` decorator, but can also be used directly. It's faster and more compact in the case where the function ``f`` already exists. """* inp = ctx.__enter__() *try*: retval = func(inp) *except*: *if* *not* ctx.__exit__(*sys.exc_info()): *raise* *else*: ctx.__exit__(None, None, None) *return* retval This version doesn't handle the multi-context syntax of newer pythons, but could probably be extended readily enough.
_______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com