Cómo ignorar correctamente las excepciones
Cuando solo desea hacer un intento-excepto sin manejar la excepción, ¿cómo lo hace en Python?
¿Es la siguiente la manera correcta de hacerlo?
try:
shutil.rmtree(path)
except:
pass
11 answers
try:
doSomething()
except:
pass
O
try:
doSomething()
except Exception:
pass
La diferencia es que el primero también atrapará KeyboardInterrupt
, SystemExit
y cosas así, que se derivan directamente de exceptions.BaseException
, no exceptions.Exception
.
Ver documentación para más detalles:
- sentencia try - http://docs.python.org/reference/compound_stmts.html#try
- excepciones - http://docs.python.org/library/exceptions
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-04-08 16:37:49
Generalmente se considera una mejor práctica detectar solo los errores que le interesan. En el caso de shutil.rmtree
es probablemente OSError
:
>>> shutil.rmtree("/fake/dir")
Traceback (most recent call last):
[...]
OSError: [Errno 2] No such file or directory: '/fake/dir'
Si quieres ignorar silenciosamente ese error, debes hacer: {[18]]}
try:
shutil.rmtree(path)
except OSError:
pass
¿Por qué? Digamos que (de alguna manera) accidentalmente pasa a la función un entero en lugar de una cadena, como:
shutil.rmtree(2)
Dará el error "TypeError: coercing to Unicode: need string or buffer, int found" - probablemente no quieras ignorar eso, lo que puede ser difícil de depurar.
Si definitivamente desea ignorar todos los errores, capture Exception
en lugar de una simple declaración except:
. Otra vez, ¿por qué?
No especificando una excepción captura cada excepción, incluida la SystemExit
excepción que por ejemplo sys.exit()
utiliza:
>>> try:
... sys.exit(1)
... except:
... pass
...
>>>
Compare esto con lo siguiente, que sale correctamente:{[18]]}
>>> try:
... sys.exit(1)
... except Exception:
... pass
...
shell:~$
Si desea escribir un código que se comporta cada vez mejor, el OSError
la excepción puede representar varios errores, pero en el ejemplo anterior solo queremos ignorar Errno 2
, por lo que podríamos ser aún más específicos:
try:
shutil.rmtree(path)
except OSError, e:
if e.errno == 2:
# suppress "No such file or directory" error
pass
else:
# reraise the exception, as it's an unexpected error
raise
También puede import errno
y cambiar el if
a if e.errno == errno.ENOENT:
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-25 09:58:57
Cuando solo quieres hacer una captura de prueba sin manejar la excepción, ¿cómo lo haces en Python?
Depende de lo que quieres decir con "manejo."
Si quieres atraparlo sin tomar ninguna acción, el código que publicaste funcionará.
Si quieres decir que quieres tomar acción sobre una excepción sin detener la excepción de subir a la pila, entonces quieres algo como esto:
try:
do_something()
except:
handle_exception()
raise #re-raise the exact same exception that was thrown
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-04-08 16:32:32
Primero cito la respuesta de Jack o'Connor deeste hilo . El hilo referenciado se cerró así que escribo aquí:
" Hay una nueva forma de hacer esto en Python 3.4:
from contextlib import suppress
with suppress(Exception):
# your code
Aquí está el commit que lo agregó: http://hg.python.org/cpython/rev/406b47c64480
Y aquí está el autor, Raymond Hettinger, hablando de esto y todo tipo de otras picor Python: https://youtu.be/OSGv2VnC0go?t=43m23s
Mi adición a esto es el Equivalente a Python 2.7:
from contextlib import contextmanager
@contextmanager
def ignored(*exceptions):
try:
yield
except exceptions:
pass
Luego lo usas como en Python 3.4:
with ignored(Exception):
# your code
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-13 12:43:22
Para completar:
>>> def divide(x, y):
... try:
... result = x / y
... except ZeroDivisionError:
... print "division by zero!"
... else:
... print "result is", result
... finally:
... print "executing finally clause"
También tenga en cuenta que puede capturar la excepción de esta manera:
>>> try:
... this_fails()
... except ZeroDivisionError as detail:
... print 'Handling run-time error:', detail
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-13 22:16:54
¿Cómo ignorar correctamente las excepciones?
Hay varias maneras de hacer esto.
Sin embargo, la elección del ejemplo tiene una solución simple que no cubre el caso general.
Específico para el ejemplo:
En lugar de
try:
shutil.rmtree(path)
except:
pass
Haz esto:
shutil.rmtree(path, ignore_errors=True)
Este es un argumento específico de shutil.rmtree
. Puede ver la ayuda haciendo lo siguiente, y verá que también puede permitir la funcionalidad en errores como bien.
>>> import shutil
>>> help(shutil.rmtree)
Dado que esto solo cubre el caso estrecho del ejemplo, demostraré aún más cómo manejar esto si esos argumentos de palabras clave no existían.
Enfoque general
Dado que lo anterior solo cubre el caso estrecho del ejemplo, demostraré aún más cómo manejar esto si esos argumentos de palabras clave no existían.
Nuevo en Python 3.4:
Puede importar el administrador de contexto suppress
:
from contextlib import suppress
Pero solo suprimir los más específicos excepción:
with suppress(FileNotFoundError):
shutil.rmtree(path)
Ignorarás en silencio un FileNotFoundError
:
>>> with suppress(FileNotFoundError):
... shutil.rmtree('bajkjbkdlsjfljsf')
...
>>>
De los documentos :
Como con cualquier otro mecanismo que suprime completamente las excepciones, este administrador de contexto solo debe usarse para cubrir errores muy específicos donde se sabe que continuar silenciosamente con la ejecución del programa es el lo correcto.
Tenga en cuenta que suppress
y FileNotFoundError
solo están disponibles en Python 3.
Si quieres que tu código funcione en Python 2 también, ver la siguiente sección:
Python 2 & 3:
Cuando solo desea hacer un intento / excepto sin manejar la excepción, ¿cómo se hace en Python?
¿Es la siguiente la manera correcta de hacerlo?
try : shutil.rmtree ( path ) except : pass
Para el código compatible con Python 2, pass
es la forma correcta de tener una instrucción que no es operativa. Pero cuando haces un except:
desnudo, eso es lo mismo que hacer except BaseException:
que incluye GeneratorExit
, KeyboardInterrupt
, y SystemExit
, y en general, no quieres atrapa esas cosas.
De hecho, debe ser tan específico al nombrar la excepción como pueda.
Aquí está parte de la jerarquía de excepciones de Python (2) , y como puede ver, si detecta Excepciones más generales, puede ocultar problemas que no esperaba:
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
Probablemente quiera capturar un OSError aquí, y tal vez la excepción que no le importa es si no hay ningún directorio.
Podemos obtener ese número de error específico de la errno
biblioteca, y volver a subir si no tenemos que:
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
Tenga en cuenta que un bare raise eleva la excepción original, que es probablemente lo que desea en este caso. Escrito de forma más concisa, ya que realmente no necesitamos explícitamente pass
con código en el manejo de excepciones:
try:
shutil.rmtree(path)
except OSError as error:
if error.errno != errno.ENOENT: # no such file or directory
raise
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-19 14:38:26
@Cuando solo quieres hacer una captura de prueba sin manejar la excepción, ¿cómo lo haces en Python?
Esto le ayudará a imprimir lo que es la excepción:( es decir, intente capturar sin manejar la excepción e imprima la excepción.)
import sys .... try: doSomething() except: print "Unexpected error:", sys.exc_info()[0] ...
Reg, Tilokchan
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-12 05:36:30
try:
doSomething()
except Exception:
pass
else:
stuffDoneIf()
TryClauseSucceeds()
Para su información, la cláusula else puede ir después de todas las excepciones y solo se ejecutará si el código en el intento no causa una excepción.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-11-19 22:35:58
En Python, manejamos excepciones similares a otros lenguajes, pero la diferencia es alguna diferencia de sintaxis, por ejemplo,
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...
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-31 01:17:00
Simplemente plantea la excepción relevante, así:
try:
raise NameError('Joan')
except NameError:
print 'An exception just raised again by Joan!'
raise
Tan simple como eso. :)
Para más detalles, lea esta documentación: https://docs.python.org/3.6/tutorial/errors.html
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-03 20:21:21
Manejo de una excepción en Python: Si tiene algún código sospechoso que pueda generar una excepción, puede defender su programa colocando el código sospechoso en un bloque try:.
try:
# Your statements .............
except ExceptionI:
# Your statements.............
except ExceptionII:
# Your statements..............
else:
# Your statements
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-31 01:18:33