utilizar - try except anidados python
Cómo ignorar apropiadamente las excepciones (11)
Cuando solo quieres hacer un intento, excepto sin manejar la excepción, ¿cómo lo haces en Python?
¿Es la siguiente la forma correcta de hacerlo?
try:
shutil.rmtree(path)
except:
pass
¿Cómo ignorar adecuadamente 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
Hacer esto:
shutil.rmtree(path, ignore_errors=True)
Este es un argumento específico para shutil.rmtree
. Puede ver la ayuda en él haciendo lo siguiente, y verá que también puede permitir la funcionalidad de los errores.
>>> import shutil
>>> help(shutil.rmtree)
Como esto solo cubre el caso estrecho del ejemplo, demostraré además cómo manejar esto si esos argumentos de palabras clave no existieran.
Enfoque general
Dado que lo anterior solo cubre el caso estrecho del ejemplo, demostraré además cómo manejar esto si esos argumentos de palabras clave no existieran.
Nuevo en Python 3.4:
Puede importar el administrador de contexto de suppress
:
from contextlib import suppress
Pero solo suprimir la excepción más específica:
with suppress(FileNotFoundError):
shutil.rmtree(path)
FileNotFoundError
silenciosamente un FileNotFoundError
:
>>> with suppress(FileNotFoundError):
... shutil.rmtree(''bajkjbkdlsjfljsf'')
...
>>>
De la docs :
Al igual que con cualquier otro mecanismo que suprima por completo las excepciones, este administrador de contexto debe usarse solo para cubrir errores muy específicos en los que se sabe que continuar con la ejecución del programa es lo correcto.
Tenga en cuenta que suppress
y FileNotFoundError
solo están disponibles en Python 3.
Si también desea que su código funcione en Python 2, consulte la siguiente sección:
Python 2 y 3:
Cuando solo quieres hacer un intento / excepto sin manejar la excepción, ¿cómo lo haces en Python?
¿Es la siguiente la forma 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 declaración que no es operativa. Pero cuando haces un except BaseException:
es lo mismo que hacer, except BaseException:
que incluye GeneratorExit
, KeyboardInterrupt
, y SystemExit
, y en general, no quieres capturar esas cosas.
De hecho, debe ser tan específico al nombrar la excepción como pueda.
Esta es parte de la jerarquía de excepciones de Python (2) y, como puede ver, si detecta excepciones más generales, puede ocultar los 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 desee capturar un OSError aquí, y tal vez la excepción que no le importa es si no hay un directorio.
Podemos obtener ese número de error específico de la biblioteca errno
y volver a subir si no lo tenemos:
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 aumento simple genera la excepción original, que es probablemente lo que desea en este caso. Escrito de forma más concisa, ya que no necesitamos pass
explícitamente 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
Cuando solo quieres hacer un try catch sin manejar la excepción, ¿cómo lo haces en Python?
Depende de lo que quieras decir con "manejo".
Si pretende capturarlo sin realizar ninguna acción, el código que publicó funcionará.
Si quiere decir que desea realizar una acción en una excepción sin impedir que la excepción suba la pila, desea algo como esto:
try:
do_something()
except:
handle_exception()
raise #re-raise the exact same exception that was thrown
@Cuando solo quieres hacer un try catch sin manejar la excepción, ¿cómo lo haces en Python?
Esto le ayudará a imprimir qué 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
En Python, manejamos excepciones similares a otro lenguaje, 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...
En general, se considera una práctica recomendada solo detectar los errores que le interesan. En el caso de shutil.rmtree
es probable que 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, harías:
try:
shutil.rmtree(path)
except OSError:
pass
¿Por qué? Digamos que usted (de alguna manera) pasa accidentalmente a la función un número entero en lugar de una cadena, como:
shutil.rmtree(2)
Le dará el error " Error del tipo : coacción a Unicode: se necesita una cadena o un búfer, se encontró" , probablemente no quiera ignorarlo, lo que puede ser difícil de depurar.
Si definitivamente quiere ignorar todos los errores, capture Exception
lugar de una simple except:
De nuevo, ¿por qué?
Al no especificar una excepción, se SystemExit
todas las excepciones, incluida la excepción SystemExit
que, por ejemplo, sys.exit()
usa:
>>> try:
... sys.exit(1)
... except:
... pass
...
>>>
Compare esto con lo siguiente, que sale correctamente:
>>> try:
... sys.exit(1)
... except Exception:
... pass
...
shell:~$
Si desea escribir un código de mejor comportamiento, la excepción OSError
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:
Por completitud:
>>> def divide(x, y):
... try:
... result = x / y
... except ZeroDivisionError:
... print "division by zero!"
... else:
... print "result is", result
... finally:
... print "executing finally clause"
... del tutorial de python .
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
Primero cito la respuesta de Jack o''Connor de este hilo . El hilo de referencia se cerró, así que escribo aquí:
"Hay una nueva forma de hacerlo en Python 3.4:
from contextlib import suppress
with suppress(Exception):
# your code
Aquí está el compromiso que lo agregó: http://hg.python.org/cpython/rev/406b47c64480
Y aquí está el autor, Raymond Hettinger, hablando de esto y de todo otro tipo de picor de Python: https://youtu.be/OSGv2VnC0go?t=43m23s
Mi adición a esto es el equivalente de 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
Simplemente levante la excepción relevante, así:
try:
raise NameError(''Joan'')
except NameError:
print ''An exception just raised again by Joan!''
raise
Tan sencillo como eso. :)
Para obtener más detalles, lea esta documentación: https://docs.python.org/3.6/tutorial/errors.html
Manejo de una excepción en Python: si tiene algún código sospechoso que puede provocar 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
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.
try:
doSomething()
except:
pass
o
try:
doSomething()
except Exception:
pass
La diferencia es que el primero también detectará KeyboardInterrupt
, SystemExit
y cosas por el estilo, que se derivan directamente de las exceptions.BaseException
, no exceptions.Exception
.
Consulte la documentación para más detalles:
- Declaración de prueba: http://docs.python.org/reference/compound_stmts.html#try
- excepciones - http://docs.python.org/library/exceptions