Vous pourriez (ab)utiliser des décorateurs pour faire cela, je pense. Ce qui suit fonctionne, par exemple :
def execute_with_context_manager(man):
def decorator(f):
target = man.__enter__()
exc = True
try:
try:
f(target)
except:
exc = False
if not man.__exit__(*sys.exc_info()):
raise
finally:
if exc:
man.__exit__(None, None, None)
return None
return decorator
@execute_with_context_manager(open("/etc/motd"))
def inside(motd_file):
for line in motd_file:
print line,
(Bon, dans Python 2.4 les objets fichiers n'ont pas de méthodes __enter__ et __exit__, mais sinon ça marche)
L'idée est que vous remplacez la ligne avec dans :
with bar() as foo:
do_something_with(foo)
do_something_else_with(foo)
# etc...
avec la fonction décorée "déclaration" dans :
@execute_with_context_manager( bar() )
def dummyname( foo ):
do_something_with(foo)
do_something_else_with(foo)
# etc...
mais on obtient le même comportement (le code do_something_... exécuté). Notez que le décorateur change la déclaration de la fonction en une fonction recours immédiat ce qui est plus qu'un peu maléfique.