Lorsque vous voulez simplement faire un essai, sauf sans gérer l'exception, comment faites-vous en Python?
Est-ce que la bonne façon de procéder est la suivante?
try:
shutil.rmtree(path)
except:
pass
try: rob() except: run()
Lorsque vous voulez simplement faire un essai, sauf sans gérer l'exception, comment faites-vous en Python?
Est-ce que la bonne façon de procéder est la suivante?
try:
shutil.rmtree(path)
except:
pass
try: rob() except: run()
Réponses:
try:
doSomething()
except:
pass
ou
try:
doSomething()
except Exception:
pass
La différence est que le premier attrapera également KeyboardInterrupt
, SystemExit
et des trucs comme ça, qui sont dérivés directement de exceptions.BaseException
, non exceptions.Exception
.
Voir la documentation pour plus de détails:
try: shuti.rmtree(...) except: pass
supprimera grossièrement toutes les erreurs (même si vous mal orthographié shutil
résultant en un NameError
) - à tout le moinsexcept OSError:
Il est généralement considéré comme la meilleure pratique de ne détecter que les erreurs qui vous intéressent. Dans le cas, 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 feriez:
try:
shutil.rmtree(path)
except OSError:
pass
Pourquoi? Supposons que vous (en quelque sorte) transmettez accidentellement à la fonction un entier au lieu d'une chaîne, comme:
shutil.rmtree(2)
Cela donnera l'erreur "TypeError: coercing to Unicode: need string or buffer, int found" - vous ne voudrez probablement pas ignorer cela, ce qui peut être difficile à déboguer.
Si vous voulez vraiment ignorer toutes les erreurs, attrapez Exception
plutôt qu'une simple except:
déclaration. Encore une fois, pourquoi?
Ne pas spécifier d'exception intercepte toutes les exceptions, y compris l' SystemExit
exception qui sys.exit()
utilise par exemple :
>>> try:
... sys.exit(1)
... except:
... pass
...
>>>
Comparez cela aux éléments suivants, qui se terminent correctement:
>>> try:
... sys.exit(1)
... except Exception:
... pass
...
shell:~$
Si vous voulez écrire du code qui se comporte toujours mieux, l' OSError
exception peut représenter diverses erreurs, mais dans l'exemple ci-dessus, nous voulons seulement ignorer Errno 2
, donc nous pourrions être encore plus spécifiques:
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
shutil.rmtree
n'est pas le meilleur exemple, car vous utiliseriez simplement ignore_errors=True
cette fonction ..
Lorsque vous voulez simplement faire un essai de capture sans gérer l'exception, comment le faites-vous en Python?
Cela dépend de ce que vous entendez par «manipulation».
Si vous voulez l'attraper sans rien faire, le code que vous avez publié 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
Je cite d'abord la réponse de Jack o'Connor de ce fil . Le fil référencé a été fermé donc j'écris ici:
"Il existe une nouvelle façon de faire cela à venir 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 cela et de toutes sortes d'autres points forts de Python: https://youtu.be/OSGv2VnC0go?t=43m23s
Mon ajout à cela est l'équivalent 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
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 relancez l'exception comme ceci:
>>> try:
... raise NameError('HiThere')
... except NameError:
... print('An exception flew by!')
... raise
... des exemples du tutoriel python .
Comment ignorer correctement les exceptions?
Il existe plusieurs façons de procéder.
Cependant, le choix de l'exemple a une solution simple qui ne couvre pas le cas général.
Au lieu de
try:
shutil.rmtree(path)
except:
pass
Faites ceci:
shutil.rmtree(path, ignore_errors=True)
Il s'agit d'un argument spécifique à shutil.rmtree
. Vous pouvez voir l'aide à ce sujet en procédant comme suit, et vous verrez qu'il peut également permettre la fonctionnalité sur les erreurs.
>>> import shutil
>>> help(shutil.rmtree)
Étant donné que cela ne couvre que le cas étroit de l'exemple, je vais montrer plus en détail comment gérer cela si ces arguments de mots clés n'existaient pas.
Étant donné que ce qui précède ne couvre que le cas étroit de l'exemple, je vais montrer plus en détail comment gérer cela si ces arguments de mots clés n'existaient pas.
Vous pouvez importer le suppress
gestionnaire de contexte:
from contextlib import suppress
Mais ne supprimez que l'exception la plus spécifique:
with suppress(FileNotFoundError):
shutil.rmtree(path)
Vous ignorerez silencieusement FileNotFoundError
:
>>> with suppress(FileNotFoundError):
... shutil.rmtree('bajkjbkdlsjfljsf')
...
>>>
De la documentation :
Comme pour tout autre mécanisme qui supprime complètement les exceptions, ce gestionnaire de contexte ne doit être utilisé que pour couvrir des erreurs très spécifiques lorsque la poursuite silencieuse de l'exécution du programme est la bonne chose à faire.
Notez que suppress
et FileNotFoundError
ne sont disponibles qu'en Python 3.
Si vous souhaitez que votre code fonctionne également en Python 2, consultez la section suivante:
Lorsque vous voulez juste faire un essai / sauf sans gérer l'exception, comment faites-vous en Python?
Est-ce que la bonne façon de procéder est la suivante?
try : shutil.rmtree ( path ) except : pass
Pour le code compatible Python 2, pass
est la bonne façon d'avoir une déclaration qui est un no-op. Mais quand vous faites un nu except:
, qui est la même chose que faire ce except BaseException:
qui comprend GeneratorExit
, KeyboardInterrupt
et SystemExit
, en général, vous ne voulez pas attraper ces choses.
En fait, vous devez être aussi précis que possible pour nommer l'exception.
Voici une partie de la hiérarchie des exceptions Python (2) , et comme vous pouvez le voir, si vous interceptez des exceptions plus générales, vous pouvez masquer les problèmes auxquels vous ne vous attendiez pas:
BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
+-- StopIteration
+-- StandardError
| +-- BufferError
| +-- ArithmeticError
| | +-- FloatingPointError
| | +-- OverflowError
| | +-- ZeroDivisionError
| +-- AssertionError
| +-- AttributeError
| +-- EnvironmentError
| | +-- IOError
| | +-- OSError
| | +-- WindowsError (Windows)
| | +-- VMSError (VMS)
| +-- EOFError
... and so on
Vous voulez probablement attraper une OSError ici, et peut-être que l'exception dont vous vous souciez est s'il n'y a pas de répertoire.
Nous pouvons obtenir ce numéro d'erreur spécifique dans la errno
bibliothèque et relancer si nous ne l'avons pas:
import errno
try:
shutil.rmtree(path)
except OSError as error:
if error.errno == errno.ENOENT: # no such file or directory
pass
else: # we had an OSError we didn't expect, so reraise it
raise
Remarque, une augmentation nue déclenche l'exception d'origine, ce qui est probablement ce que vous voulez dans ce cas. Écrit de manière plus concise, car nous n'avons pas vraiment besoin de le faire explicitement pass
avec du code dans la gestion des exceptions:
try:
shutil.rmtree(path)
except OSError as error:
if error.errno != errno.ENOENT: # no such file or directory
raise
Lorsque vous voulez simplement faire un essai de capture sans gérer l'exception, comment le faites-vous en Python?
Cela vous aidera à imprimer ce qu'est l'exception :( c.-à-d. Essayez d'attraper sans gérer l'exception et imprimez l'exception.)
import sys
try:
doSomething()
except:
print "Unexpected error:", sys.exc_info()[0]
try:
doSomething()
except Exception:
pass
else:
stuffDoneIf()
TryClauseSucceeds()
Pour info la clause else peut aller après toutes les exceptions et ne sera exécutée que si le code de l'essai ne provoque pas d'exception.
else
dans ce contexte. Et d'ajouter que finally
sera toujours courir après tout (ou pas exception).
J'avais besoin d'ignorer les erreurs dans plusieurs commandes et putain a fait l'affaire
import fuckit
@fuckit
def helper():
print('before')
1/0
print('after1')
1/0
print('after2')
helper()
En Python, nous gérons des exceptions similaires à d'autres langages, mais la différence est une différence de syntaxe, par exemple,
try:
#Your code in which exception can occur
except <here we can put in a particular exception name>:
# We can call that exception here also, like ZeroDivisionError()
# now your code
# We can put in a finally block also
finally:
# Your code...
Je fais habituellement juste:
try:
doSomething()
except:
_ = ""
_ = ""
par pass
.
shutil.rmtree(path, ignore_errors=True)
. Cependant, cela ne s'applique pas à la plupart des fonctions.