Cuando solo quieres probar, 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
try: rob() except: run()
Cuando solo quieres probar, 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
try: rob() except: run()
Respuestas:
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
.
Consulte la documentación para más detalles:
try: shuti.rmtree(...) except: pass
suprimirá crudamente cualquier error (incluso si shutil
NameError
except OSError:
En general, se considera una práctica recomendada detectar solo los errores que le interesan. En el caso de shutil.rmtree
que sea probable OSError
:
>>> shutil.rmtree("/fake/dir")
Traceback (most recent call last):
[...]
OSError: [Errno 2] No such file or directory: '/fake/dir'
Si quiere ignorar silenciosamente ese error, haría:
try:
shutil.rmtree(path)
except OSError:
pass
¿Por qué? Digamos que (de alguna manera) accidentalmente pasa la función a un entero en lugar de una cadena, como:
shutil.rmtree(2)
Aparecerá el error "TypeError: coaccionar a Unicode: necesita cadena o buffer, int encontrado" - probablemente no quiera ignorar eso, lo que puede ser difícil de depurar.
Si definitivamente desea ignorar todos los errores, capture en Exception
lugar de una except:
declaración simple . De nuevo por qué?
Al no especificar una excepción, se detectan todas las excepciones, 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:
>>> try:
... sys.exit(1)
... except Exception:
... pass
...
shell:~$
Si desea escribir un código de comportamiento cada vez mejor, la OSError
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:
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
no es el mejor ejemplo, porque solo lo ignore_errors=True
Cuando solo quieres hacer un intento de captura sin manejar la excepción, ¿cómo lo haces en Python?
Depende de lo que quieras decir con "manipulación".
Si quiere atraparlo sin realizar ninguna acción, el código que publicó funcionará.
Si quiere decir que desea tomar medidas sobre una excepción sin detener la subida de la excepción, entonces quiere algo como esto:
try:
do_something()
except:
handle_exception()
raise #re-raise the exact same exception that was thrown
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 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 sobre esto y todo tipo de otras características de 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
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")
También tenga en cuenta que puede capturar la excepción de esta manera:
>>> try:
... this_fails()
... except ZeroDivisionError as err:
... print("Handling run-time error:", err)
... y vuelve a plantear la excepción así:
>>> try:
... raise NameError('HiThere')
... except NameError:
... print('An exception flew by!')
... raise
... ejemplos del tutorial de Python .
¿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.
En vez 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 al hacer lo siguiente, y verá que también puede permitir la funcionalidad en los errores.
>>> import shutil
>>> help(shutil.rmtree)
Como esto solo cubre el caso estrecho del ejemplo, demostraré aún más cómo manejar esto si esos argumentos de palabras clave no existieran.
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 existieran.
Puede importar el suppress
administrador de contexto:
from contextlib import suppress
Pero solo suprima la excepción más específica:
with suppress(FileNotFoundError):
shutil.rmtree(path)
Ignorarás silenciosamente un FileNotFoundError
:
>>> with suppress(FileNotFoundError):
... shutil.rmtree('bajkjbkdlsjfljsf')
...
>>>
De los documentos :
Al igual que con cualquier otro mecanismo que suprima completamente las excepciones, este administrador de contexto debe usarse solo para cubrir errores muy específicos en los que se sabe que continuar silenciosamente con la ejecución del programa es lo correcto.
Tenga en cuenta que suppress
y FileNotFoundError
solo están disponibles en Python 3.
Si desea que su código también funcione en Python 2, consulte la siguiente sección:
Cuando solo quieres probar / 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 sea operativa. Pero cuando se hace una desnuda except:
, eso es lo mismo que hacer except BaseException:
que incluye GeneratorExit
, KeyboardInterrupt
y SystemExit
, y, en general, que no quieren coger esas cosas.
De hecho, debe ser tan específico al nombrar la excepción como sea posible.
Aquí hay 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 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 errno
biblioteca y volver a subirlo si no tenemos eso:
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 probablemente es lo que desea en este caso. Escrito de manera más concisa, ya que realmente no necesitamos explícitamente pass
con el 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 intento de captura sin manejar la excepción, ¿cómo lo haces en Python?
Esto lo ayudará a imprimir cuál 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]
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.
else
en este contexto. Y añadir que finally
será siempre correr detrás de cualquiera (o no es una excepción).
Necesitaba ignorar los errores en múltiples comandos y eso fue lo que hice.
import fuckit
@fuckit
def helper():
print('before')
1/0
print('after1')
1/0
print('after2')
helper()
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...
Usualmente solo hago:
try:
doSomething()
except:
_ = ""
_ = ""
con pass
.
shutil.rmtree(path, ignore_errors=True)
. Sin embargo, esto no se aplicará a la mayoría de las funciones.