Je voudrais juste sortir d'une déclaration with
sous certaines conditions:
with open(path) as f:
print 'before condition'
if <condition>: break #syntax error!
print 'after condition'
Bien sûr, ce qui précède ne fonctionne pas. Y a-t-il un moyen de faire cela? (Je sais que je peux inverser la condition: if not <condition>: print 'after condition'
- de la même manière que ci-dessus?)
Le meilleur moyen serait de l'encapsuler dans une fonction et d'utiliser return
:
def do_it():
with open(path) as f:
print 'before condition'
if <condition>:
return
print 'after condition'
with
vous causer des ennuis? Jetez plus d'objets with
- capables au problème!
class fragile(object):
class Break(Exception):
"""Break out of the with statement"""
def __init__(self, value):
self.value = value
def __enter__(self):
return self.value.__enter__()
def __exit__(self, etype, value, traceback):
error = self.value.__exit__(etype, value, traceback)
if etype == self.Break:
return True
return error
Enveloppez simplement l'expression que vous allez utiliser with
avec fragile
, et raise fragile.Break
pour qu'elle éclate à tout moment!
with fragile(open(path)) as f:
print 'before condition'
if condition:
raise fragile.Break
print 'after condition'
with
et juste le with
; ne place pas votre fonction dans une "boucle" sémantiquement trompeuse ou une fonction étroitement spécialisée, et ne vous oblige pas à gérer les erreurs en plus après le with
.Nestable!
with fragile(open(path1)) as f:
with fragile(open(path2)) as g:
print f.read()
print g.read()
raise fragile.Break
print "This wont happen"
print "This will though!"
De cette façon, vous n'avez pas besoin de créer une nouvelle fonction pour envelopper le with
extérieur si vous voulez que les deux se cassent.
fragile
et vous voilà prêt à partir!Je pense que vous devriez simplement restructurer la logique:
with open(path) as f:
print 'before condition checked'
if not <condition>:
print 'after condition checked'
Puisque break
ne peut apparaître qu’à l’intérieur d’une boucle, vos options sont quelque peu limitées dans with
à:
Avoir une fonction et utiliser return
est probablement la solution la plus propre et la plus simple ici si vous pouvez isoler la with
et les instructions associées (et rien d’autre) à l’intérieur d’une fonction.
Sinon, générez une exception dans la with
si nécessaire, interceptez immédiatement en dessous/en dehors de la with
pour continuer le reste du code.
Mise à jour : Comme OP le suggère dans les commentaires ci-dessous (peut-être tonuge à la joue?), On pourrait également envelopper la déclaration with
dans une boucle pour faire fonctionner la break
- bien que ce soit sournoisement trompeur. Donc, bien qu’il s’agisse d’une solution de travail, ce n’est probablement pas quelque chose qui serait recommandé).
f = open("somefile","r")
for line in f.readlines():
if somecondition: break;
f.close()
Je ne pense pas que vous puissiez sortir de la ... vous devez utiliser une boucle ...
[edit] ou faites simplement la méthode de la fonction mentionnée par les autres
C’est une question ancienne, mais c’est une application de l’idiome pratique «à portée cassable». Intégrez simplement votre déclaration with
à l'intérieur:
for _ in (True,):
with open(path) as f:
print 'before condition'
if <condition>: break
print 'after condition'
Cet idiome crée une "boucle", toujours exécutée exactement une fois, dans le seul but de renfermer un bloc de code dans une portée qui peut être rompue de manière conditionnelle. Dans le cas d'OP, il s'agissait d'une invocation de gestionnaire de contexte à inclure, mais il pouvait s'agir de toute séquence d'instructions délimitées pouvant nécessiter un échappement conditionnel.
La réponse acceptée est acceptable, mais cette technique fait la même chose sans qu'il soit nécessaire de créer une fonction, ce qui n'est pas toujours pratique ou souhaité.
comme extrait abrégé:
class a:
def __enter__(self):
print 'enter'
def __exit__(self ,type, value, traceback):
print 'exit'
for i in [1]:
with a():
print("before")
break
print("after")
...
enter
before
exit
Vous pouvez tout mettre dans une fonction et lorsque la condition est vraie, appelez un retour.
Il existe une fonction __exit__()
à cet effet. La syntaxe est la suivante:
with VAR = EXPR:
try:
BLOCK
finally:
VAR.__exit__()