Attraper une exception dans le gestionnaire de contexte __enter __ ()
Est-il possible de s'assurer de la __exit__()
méthode est appelée, même si il y a une exception dans __enter__()
?
>>> class TstContx(object):
... def __enter__(self):
... raise Exception('Oops in __enter__')
...
... def __exit__(self, e_typ, e_val, trcbak):
... print "This isn't running"
...
>>> with TstContx():
... pass
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in __enter__
Exception: Oops in __enter__
>>>
Modifier
C'est aussi proche que j'ai pu obtenir...
class TstContx(object):
def __enter__(self):
try:
# __enter__ code
except Exception as e
self.init_exc = e
return self
def __exit__(self, e_typ, e_val, trcbak):
if all((e_typ, e_val, trcbak)):
raise e_typ, e_val, trcbak
# __exit__ code
with TstContx() as tc:
if hasattr(tc, 'init_exc'): raise tc.init_exc
# code in context
Dans les postérieurs de la vue, un gestionnaire de contexte pourraient ne pas avoir été la meilleure décision de conception
source d'informationauteur tMC
Vous devez vous connecter pour publier un commentaire.
Comme ceci:
De laisser le programme de continuer son petit bonhomme de chemin sans exécuter le contexte de bloc, vous devez vérifier le contexte de l'objet à l'intérieur du contexte de bloc et ne faire que les choses importantes, si
__enter__
réussi.Pour autant que je puisse en juger, vous ne pouvez pas sauter le avec bloc entièrement. Et notez que ce contexte avale maintenant tous exceptions. Si vous souhaitez ne pas avaler des exceptions si
__enter__
réussit, vérifierself.enter_ok
dans__exit__
etreturn False
si c'estTrue
.Pas. Si il ya la possibilité qu'une exception peut se produire dans
__enter__()
alors vous aurez besoin de l'attraper vous-même et d'appeler une fonction d'aide qui contient le code de nettoyage.Vous pouvez utiliser
contextlib.ExitStack
(pas testé):Ou un exemple de les docs:
Voir contextlib2 sur Python <3.3.
si l'héritage ou complexe de sous-programmes ne sont pas nécessaires, vous pouvez utiliser un moyen plus court:
Je l'ai fait comme cela. Il appelle __exit__() avec l'erreur comme argument. Si args[0] contient une erreur, il reraises l'exception après l'exécution de la nettoyer le code.