950 votes

Comment ignorer correctement les exceptions

Lorsque vous voulez simplement faire un try-except sans gérer l'exception, comment faites-vous en Python ?

La méthode suivante est-elle la bonne ?

try:
    shutil.rmtree(path)
except:
    pass

17 votes

Bizarre que personne ne l'ait mentionné jusqu'à présent (je l'ai fait dans ma réponse), mais pour cette fonction spécifique, vous pouvez simplement faire shutil.rmtree(path, ignore_errors=True) . Cela ne s'applique toutefois pas à la plupart des fonctions.

11 votes

Lecture importante lorsque l'on pense à ignorer les exceptions : Pourquoi "except : pass" est-il une mauvaise pratique de programmation ?

6 votes

Imaginez faire ceci dans la vie réelle. essayez : get_cash('$1000') except : pass # meh, it will probably be fine

1219voto

vartec Points 53382
try:
    doSomething()
except: 
    pass

o

try:
    doSomething()
except Exception: 
    pass

La différence est que le premier attrapera également KeyboardInterrupt , SystemExit et d'autres choses de ce genre, qui sont directement dérivées de exceptions.BaseException pas exceptions.Exception .

Voir la documentation pour plus de détails :

5 votes

Notez que StopIteration et Warning héritent tous deux d'Exception également. En fonction de vos besoins, vous pouvez préférer hériter de StandardError.

1 votes

C'est vrai, mais si vous ne faites pas attention, vous pouvez rencontrer des bogues subtils (surtout si vous faites autre chose que de passer sur StopIteration).

18 votes

-1, try: shuti.rmtree(...) except: pass supprimera grossièrement toute erreur (même si vous avez mal orthographié shutil ce qui donne lieu à un NameError ) - à tout le moins, faites except OSError:

165voto

dbr Points 66401

Il est généralement considéré comme une bonne pratique de ne retenir que les erreurs qui vous intéressent. Dans le cas de shutil.rmtree c'est probablement OSError :

>>> shutil.rmtree("/fake/dir")
Traceback (most recent call last):
    [...]
OSError: [Errno 2] No such file or directory: '/fake/dir'

Si vous voulez ignorer silencieusement cette erreur, vous pouvez le faire :

try:
    shutil.rmtree(path)
except OSError:
    pass

Pourquoi ? Supposons que vous transmettiez accidentellement à la fonction un nombre entier au lieu d'une chaîne de caractères, par exemple :

shutil.rmtree(2)

Il donnera l'erreur "TypeError : coercing to Unicode : need string or buffer, int found" (Erreur de type : passage à l'Unicode : chaîne de caractères ou tampon, int trouvé) - vous ne voulez probablement pas l'ignorer, ce qui peut être difficile à déboguer.

Si vous définitivement vous voulez ignorer toutes les erreurs, attraper Exception plutôt qu'un simple except: déclaration. Encore une fois, pourquoi ?

Ne pas spécifier d'exception permet d'attraper chaque l'exception, y compris le SystemExit exception qui, par exemple sys.exit() utilise :

>>> try:
...     sys.exit(1)
... except:
...     pass
... 
>>>

Comparez cela à l'exemple suivant, qui sort correctement :

>>> try:
...     sys.exit(1)
... except Exception:
...     pass
... 
shell:~$ 

Si vous voulez écrire un code qui se comporte toujours mieux, la fonction OSError L'exception peut représenter diverses erreurs, mais dans l'exemple ci-dessus, nous voulons seulement ignorer Errno 2 Nous pourrions donc être encore plus précis :

import errno

try:
    shutil.rmtree(path)
except OSError as e:
    if e.errno != errno.ENOENT:
        # ignore "No such file or directory", but re-raise other errors
        raise

3 votes

shutil.rmtree n'est pas le meilleur exemple, car vous utiliseriez simplement ignore_errors=True pour cette fonction..

1 votes

J'aime vraiment cette réponse, mais vous n'avez pas expliqué comment vous êtes passé de Errno 2 a errno.ENOENT .. Pourrait être utile pour beaucoup de gens ;) Voir Python Standard Errno System Symbols pour plus d'informations.

122voto

Jabba Points 1664

Je cite d'abord la réponse de Jack o'Connor de ce fil . Le fil de discussion référencé a été fermé, alors j'écris ici :

"Il y a une nouvelle façon de le faire dans Python 3.4 :

from contextlib import suppress

with suppress(Exception):
    # your code

Voici le commit qui l'a ajouté : http://hg.python.org/cpython/rev/406b47c64480

Et voici l'auteur, Raymond Hettinger, qui parle de cette question et de toutes sortes d'autres sujets brûlants concernant les Pythons : https://youtu.be/OSGv2VnC0go?t=43m23s

J'y ajoute l'équivalent de Python 2.7 :

from contextlib import contextmanager

@contextmanager
def ignored(*exceptions):
    try:
        yield
    except exceptions:
        pass

Ensuite, vous l'utilisez comme dans Python 3.4 :

with ignored(Exception):
    # your code

118voto

Jason Baker Points 56682

Lorsque vous voulez simplement faire un try catch sans gérer l'exception, comment faites-vous en Python ?

Cela dépend de ce que vous entendez par "manipulation".

Si vous voulez l'attraper sans faire d'action, le code que vous avez posté fonctionnera.

Si vous voulez dire que vous voulez agir sur une exception sans empêcher l'exception de remonter la pile, alors vous voulez quelque chose comme ceci :

try:
    do_something()
except:
    handle_exception()
    raise  #re-raise the exact same exception that was thrown

60voto

cbare Points 1673

Pour être complet :

>>> def divide(x, y):
...     try:
...         result = x / y
...     except ZeroDivisionError:
...         print("division by zero!")
...     else:
...         print("result is", result)
...     finally:
...         print("executing finally clause")

Notez également que vous pouvez capturer l'exception comme ceci :

>>> try:
...     this_fails()
... except ZeroDivisionError as err:
...     print("Handling run-time error:", err)

...et relancer l'exception comme ceci :

>>> try:
...     raise NameError('HiThere')
... except NameError:
...     print('An exception flew by!')
...     raise

En outre, plusieurs types d'exception peuvent être traités sous forme de tuple entre parenthèses :

try:
    i_might_fail()
except (ValueError, TypeError) as ex:
    print('I failed with: ', ex)

...ou en tant que clauses d'exclusion séparées :

try:
    i_might_fail()
except ValueError:
    print('handling a ValueError...')
except TypeError:
    print('handling a TypeError...')

...voir le tutoriel 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