Según PEP-343, una declaración with
traduce a partir de:
with EXPR as VAR:
BLOCK
a:
mgr = (EXPR)
exit = type(mgr).__exit__ # Not calling it yet
value = type(mgr).__enter__(mgr)
exc = True
try:
try:
VAR = value # Only if "as VAR" is present
BLOCK
except:
# The exceptional case is handled here
exc = False
if not exit(mgr, *sys.exc_info()):
raise
# The exception is swallowed if exit() returns true
finally:
# The normal and non-local-goto cases are handled here
if exc:
exit(mgr, None, None, None)
Como se puede ver, no hay nada obvio que puede hacer desde la llamada al método de __enter__()
el administrador de contexto que puede omitir el cuerpo ("BLOCK
") de la sentencia with.
La gente ha hecho cosas específicas de la implementación de Python, como la manipulación de la pila de llamadas dentro de __enter__()
, en proyectos como withhacks. Recuerdo que Alex Martelli publicó un muy interesante hackeo en stackoverflow hace uno o dos años (no recuerdo suficiente de la publicación para buscar y encontrarla).
Pero la respuesta simple a su pregunta/problema es que no puede hacer lo que está preguntando, saltándose el cuerpo de la declaración con, sin recurrir a la llamada "magia profunda" (que no es necesariamente portátil entre python implementaciones). Con magia profunda, es posible que puedas hacerlo, pero te recomiendo hacer cosas como un ejercicio para ver cómo se puede hacer, nunca en un "código de producción".
Encontré esto, pero no sé cómo darle sentido ni cómo implementarlo. http://www.python.org/dev/peps/pep-0377/ ¿Hay otras formas más elegantes? –
El hecho de que sea un PEP (y la discusión de los cambios semánticos) sugiere que no se puede implementar sin recurrir a cambiar el comportamiento del intérprete. – nneonneo
obsesionado con la pulcritud? :) con A(), B(): donde B's __enter__ puede levantar algo, me parece bien. – swang