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
Author: Peter Mortensen, 2009-04-08

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:

 866
Author: vartec,
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:

 120
Author: dbr,
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
 107
Author: Jason Baker,
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
 65
Author: Jabba,
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"

...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
 54
Author: cbare,
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 
 40
Author: Aaron Hall,
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

 12
Author: Irengbam Tilokchan Singh,
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.

 8
Author: MrChrisRodriguez,
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...
 3
Author: Deepak Kumar 'SORTED',
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

 -1
Author: MHBN,
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
 -1
Author: pavuluri santhi,
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