357 votes

Comment réessayer après une exception ?

J'ai une boucle qui commence par for i in range(0, 100) . Normalement, il fonctionne correctement, mais parfois il échoue en raison des conditions du réseau. Actuellement, je l'ai configuré de manière à ce qu'en cas d'échec, il continue dans la clause except (passez au numéro suivant pour la clause except). i ).

Est-il possible pour moi de réassigner le même numéro à i et recommencer l'itération ratée de la boucle ?

1 votes

Vous pouvez utiliser range(100) sans le premier paramètre. Si vous utilisez Python 2.x, vous pouvez même utiliser xrange(100) cela génère un itérateur et utilise moins de mémoire. (Non pas que cela importe avec seulement 100 objets).

11 votes

2 votes

Il existe une solution très élégante utilisant des décorateurs avec prise en charge des exceptions arbitraires dans ce fil de discussion.

494voto

zneak Points 45458

Faites un while True dans votre boucle for, mettez votre try code à l'intérieur, et de rompre à partir de ce while boucle uniquement lorsque votre code réussit.

for i in range(0,100):
    while True:
        try:
            # do stuff
        except SomeSpecificException:
            continue
        break

0 votes

continue n'utilise pas le même élément de l'itérable, mais passe au suivant.

0 votes

@Ignacio : ouais ; où est le problème ?

0 votes

@zneak : "Je me demandais s'il était possible pour moi de réaffecter le même nombre à i et de recommencer l'itération ratée de la boucle."

297voto

xorsyst Points 1099

Je préfère limiter le nombre de tentatives, de sorte que s'il y a un problème avec cet article spécifique, vous passerez éventuellement à l'article suivant :

for i in range(100):
  for attempt in range(10):
    try:
      # do thing
    except:
      # perhaps reconnect, etc.
    else:
      break
  else:
    # we failed all the attempts - deal with the consequences.

0 votes

Quelles sont les conséquences de la seconde else en ce qui concerne le contrôle des flux ? Dans quelles circonstances la partie "we failed..." du code est-elle exécutée ?

4 votes

@g33kz0r la construction for-else en Python exécute la clause else si la boucle for n'est pas interrompue. Donc, dans ce cas, cette section s'exécute si nous essayons les 10 tentatives et obtenons toujours une exception.

10 votes

C'est une excellente réponse ! Elle mérite vraiment beaucoup plus de votes positifs. Elle utilise parfaitement toutes les facilités de Python, notamment la moins connue else: clause de for .

100voto

goneri Points 41

El paquet de relance est un bon moyen de réessayer un bloc de code en cas d'échec.

Par exemple :

@retry(wait_random_min=1000, wait_random_max=2000)
def wait_random_1_to_2_s():
    print("Randomly wait 1 to 2 seconds between retries")

4 votes

Plus généralement, pypi dispose de plusieurs paquets pour les décorateurs de relance : pypi.python.org/

0 votes

Est-il possible d'imprimer le numéro de la tentative de réessai à chaque fois qu'elle échoue ?

20 votes

Comme je l'ai compris n'est pas maintenu, une fourche plus active est github.com/jd/tenacity et peut-être github.com/litl/backoff peut également être utilisé.

11voto

Tomi Kyöstilä Points 743

La manière la plus claire serait de définir explicitement le paramètre i . Par exemple :

i = 0
while i < 100:
    i += 1
    try:
        # do stuff

    except MyException:
        continue

44 votes

C'est du C ou du C++ ? Je n'arrive pas à savoir.

5 votes

@Georg C'est Python, comme indiqué dans la question. Ou bien êtes-vous sarcastique pour une raison quelconque ?

3 votes

Cela ne fait pas ce que le PO a demandé. Cela pourrait le faire si vous mettiez i += 1 juste après # do stuff .

4voto

Michael Points 501

Il y a quelque chose de similaire dans le Bibliothèque de décorateurs Python .

N'oubliez pas qu'il ne teste pas les exceptions, mais la valeur de retour. Elle réessaie jusqu'à ce que la fonction décorée renvoie True.

Une version légèrement modifiée devrait faire l'affaire.

2 votes

Voici comment le modifier pour les exceptions saltycrane.com/blog/2009/11/trying-out-retry-decorator-python

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X