Quando você só quer fazer uma tentativa, exceto sem manipular a exceção, como você faz isso no Python?
O seguinte é o caminho certo para fazer isso?
try:
shutil.rmtree(path)
except:
pass
try: rob() except: run()
Quando você só quer fazer uma tentativa, exceto sem manipular a exceção, como você faz isso no Python?
O seguinte é o caminho certo para fazer isso?
try:
shutil.rmtree(path)
except:
pass
try: rob() except: run()
Respostas:
try:
doSomething()
except:
pass
ou
try:
doSomething()
except Exception:
pass
A diferença é que o primeiro também vai pegar KeyboardInterrupt
, SystemExit
e coisas assim, que são derivadas diretamente exceptions.BaseException
, não exceptions.Exception
.
Consulte a documentação para obter detalhes:
try: shuti.rmtree(...) except: pass
suprimirá de forma grosseira quaisquer erros (mesmo se você cometer shutil
um erro de ortografia resultando em a NameError
) - pelo menosexcept OSError:
Geralmente, é considerado uma boa prática capturar apenas os erros nos quais você está interessado. No caso shutil.rmtree
, provavelmente OSError
:
>>> shutil.rmtree("/fake/dir")
Traceback (most recent call last):
[...]
OSError: [Errno 2] No such file or directory: '/fake/dir'
Se você deseja ignorar silenciosamente esse erro, faça:
try:
shutil.rmtree(path)
except OSError:
pass
Por quê? Digamos que você (de alguma forma) passe acidentalmente a função um número inteiro em vez de uma string, como:
shutil.rmtree(2)
Ele exibirá o erro "TypeError: coagindo para Unicode: precisa de string ou buffer, int encontrado" - você provavelmente não deseja ignorar isso, o que pode ser difícil de depurar.
Se você definitivamente deseja ignorar todos os erros, pegue em Exception
vez de uma except:
declaração simples . Novamente, por que?
Não especificar uma exceção captura todas as exceções, incluindo a SystemExit
exceção que, por exemplo, sys.exit()
usa:
>>> try:
... sys.exit(1)
... except:
... pass
...
>>>
Compare isso com o seguinte, que sai corretamente:
>>> try:
... sys.exit(1)
... except Exception:
... pass
...
shell:~$
Se você deseja escrever um código de comportamento cada vez melhor, a OSError
exceção pode representar vários erros, mas no exemplo acima, queremos apenas ignorar Errno 2
, para que possamos ser ainda mais 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
não é o melhor exemplo, porque você usaria apenas ignore_errors=True
para essa função ..
Quando você deseja apenas tentar capturar sem manipular a exceção, como você faz isso no Python?
Depende do que você quer dizer com "manuseio".
Se você deseja capturá-lo sem executar nenhuma ação, o código que você postou funcionará.
Se você quer dizer que deseja executar uma exceção sem interromper a exceção de subir a pilha, então deseja algo como isto:
try:
do_something()
except:
handle_exception()
raise #re-raise the exact same exception that was thrown
Primeiro cito a resposta de Jack o'Connor neste tópico . O thread referenciado foi fechado, então eu escrevo aqui:
"Existe uma nova maneira de fazer isso no Python 3.4:
from contextlib import suppress
with suppress(Exception):
# your code
Aqui está o commit que o adicionou: http://hg.python.org/cpython/rev/406b47c64480
E aqui está o autor, Raymond Hettinger, falando sobre isso e todos os tipos de gostosuras de Python: https://youtu.be/OSGv2VnC0go?t=43m23s
Minha adição a isso é o equivalente ao Python 2.7:
from contextlib import contextmanager
@contextmanager
def ignored(*exceptions):
try:
yield
except exceptions:
pass
Então você o usa como no Python 3.4:
with ignored(Exception):
# your code
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")
Observe também que você pode capturar a exceção assim:
>>> try:
... this_fails()
... except ZeroDivisionError as err:
... print("Handling run-time error:", err)
... e redigite a exceção assim:
>>> try:
... raise NameError('HiThere')
... except NameError:
... print('An exception flew by!')
... raise
... exemplos do tutorial python .
Como ignorar corretamente exceções?
Existem várias maneiras de fazer isso.
No entanto, a escolha do exemplo tem uma solução simples que não cobre o caso geral.
Ao invés de
try:
shutil.rmtree(path)
except:
pass
Faça isso:
shutil.rmtree(path, ignore_errors=True)
Este é um argumento específico para shutil.rmtree
. Você pode ver a ajuda fazendo o seguinte, e também pode permitir a funcionalidade de erros.
>>> import shutil
>>> help(shutil.rmtree)
Como isso cobre apenas o caso restrito do exemplo, demonstrarei mais detalhadamente como lidar com isso se esses argumentos de palavra-chave não existirem.
Como o descrito acima cobre apenas o caso restrito do exemplo, demonstrarei mais detalhadamente como lidar com isso se esses argumentos de palavra-chave não existirem.
Você pode importar o suppress
gerenciador de contexto:
from contextlib import suppress
Mas suprima apenas a exceção mais específica:
with suppress(FileNotFoundError):
shutil.rmtree(path)
Você ignorará silenciosamente um FileNotFoundError
:
>>> with suppress(FileNotFoundError):
... shutil.rmtree('bajkjbkdlsjfljsf')
...
>>>
Dos documentos :
Como com qualquer outro mecanismo que suprime completamente as exceções, esse gerenciador de contexto deve ser usado apenas para cobrir erros muito específicos, onde a continuação silenciosa da execução do programa é conhecida como a coisa certa a se fazer.
Observe que suppress
e FileNotFoundError
só estão disponíveis no Python 3.
Se você deseja que seu código funcione também no Python 2, consulte a próxima seção:
Quando você só quer fazer uma tentativa / exceto sem manipular a exceção, como você faz isso no Python?
O seguinte é o caminho certo para fazer isso?
try : shutil.rmtree ( path ) except : pass
Para código compatível com Python 2, pass
é a maneira correta de ter uma declaração que não é operacional. Mas quando você faz um nu except:
, isso é o mesmo que fazer except BaseException:
o que inclui GeneratorExit
, KeyboardInterrupt
e SystemExit
, e, em geral, você não quer pegar essas coisas.
De fato, você deve ser o mais específico possível em nomear a exceção.
Aqui está parte da hierarquia de exceções do Python (2) e, como você pode ver, se você capturar exceções mais gerais, poderá ocultar problemas que não esperava:
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
Você provavelmente deseja capturar um OSError aqui, e talvez a exceção com a qual você não se importa seja se não houver diretório.
Podemos obter esse número de erro específico da errno
biblioteca e re-aumentar se não tivermos isso:
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
Observe que um aumento simples gera a exceção original, que provavelmente é o que você deseja neste caso. Escrito de forma mais concisa, pois não precisamos explicitamente pass
com código no tratamento de exceções:
try:
shutil.rmtree(path)
except OSError as error:
if error.errno != errno.ENOENT: # no such file or directory
raise
Quando você deseja apenas tentar capturar sem manipular a exceção, como você faz isso no Python?
Isso ajudará você a imprimir qual é a exceção :( ou seja, tente capturar sem manipular a exceção e imprima a exceção.)
import sys
try:
doSomething()
except:
print "Unexpected error:", sys.exc_info()[0]
try:
doSomething()
except Exception:
pass
else:
stuffDoneIf()
TryClauseSucceeds()
Para sua informação, a cláusula else pode ser executada após todas as exceções e só será executada se o código na tentativa não causar uma exceção.
else
para esse contexto. E para adicionar isso finally
, sempre será executado após qualquer (ou nenhuma exceção).
Eu precisava ignorar erros em vários comandos e fuckit fez o truque
import fuckit
@fuckit
def helper():
print('before')
1/0
print('after1')
1/0
print('after2')
helper()
No Python, lidamos com exceções semelhantes a outra linguagem, mas a diferença é alguma diferença de sintaxe, por exemplo,
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...
Eu costumo fazer:
try:
doSomething()
except:
_ = ""
_ = ""
por pass
.
shutil.rmtree(path, ignore_errors=True)
. Isso não se aplica à maioria das funções, no entanto.