Re: [Python-Dev] Bring new features to older python versions

2011年10月11日 09:46:00 -0700

On Tue, Oct 11, 2011 at 12:14 PM, Toshio Kuratomi <[email protected]>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
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to