Como lidar com exceções em Python
O tratamento de exceções é sua capacidade de personalizar e exibir mensagens de erro para partes do programa que não funcionam.
Esteja você construindo um site, criando uma API, um módulo ou qualquer outro produto usando Python, sua capacidade de lidar com exceções com eficácia permite que você indique explicitamente a causa de um erro.
Aqui, veremos como você pode lidar com exceções em Python.
Como funciona o tratamento de exceções em Python
Quando você levanta exceções, está dizendo ao Python para exibir uma mensagem sempre que um bloco de código falhar. O tratamento de exceções é como dizer a alguém para tentar levantar um peso. E se eles não puderem, eles devem avisar você.
Para levantar uma exceção no Python, entretanto, você dirá ao Python para tentar e executar um determinado bloco de código. Se esse bloco falhar, você pode pedir ao Python para lançar uma exceção definida para o código que falhou.
Quando você deve usar exceções na programação Python?
Na maioria das ocasiões, você pode mascarar erros padrão do Python usando exceções. Mas você precisa permanecer vigilante, pois isso pode causar problemas de depuração. Conseqüentemente, você pode achar difícil descobrir a causa raiz de um eventual bug.
Portanto, você deve usar exceções quando tiver testado suficientemente o seu código e tiver certeza de que ele funciona. Em última análise, é uma prática recomendada usá-los para lidar com possíveis falhas que podem surgir da extremidade do usuário, em vez do código em si.
Em outras palavras, você pode usar exceções como uma ferramenta de aviso para orientar os usuários sobre como usar seu programa.
Tratamento de exceções Python
Para lidar com exceções em Python, primeiro você precisa envolver seu código em um bloco try … except . Ocasionalmente, pode ser necessário incluir uma instrução finally para lidar com outras ações, dependendo de suas necessidades.
O conceito de codificação das exceções Python geralmente se parece com este:
try:
"code to be executed"
except:
"error message"
Como mencionado anteriormente, você também pode usar finally em um bloco de exceção. Mas o código que você escreve dentro de uma cláusula finally é independente e é executado independentemente de haver uma exceção ou não.
Em essência, é útil se você tiver outro bloco de código que deseja executar continuamente, independentemente do que aconteça dentro do bloco try … except .
Aqui está um exemplo:
try:
print(9+6)
except:
print("error message")
finally:
print("please restart")
Output:
15
please restart
No código acima, reinicie as execuções continuamente, independentemente de haver uma exceção ou não.
Uma condição else também pode seguir uma instrução except :
try:
C = 2 + B
except:
print("B needs to be defined")
else:
print(u"Added successfully! The result is %s"%(C))
Output: B needs to be defined
Agora tente novamente com "B" definido:
try:
B = 5
C = 2 + B
except:
print("B needs to be defined")
else:
print(u"Added successfully! The result is %s"%(C))
Output: Added successfully! The result is 7
Os exemplos acima são exceções não padronizadas. Mas você pode ter uma exceção mais explícita ao combinar exceções integradas (definidas) com as não padronizadas:
try:
C = 2 + B
except NameError as err:
print(err, ":", "B needs to be defined, please")
else:
print(u"Added successfully! The result is %s"%(C))
Output: name 'B' is not defined : B needs to be defined, please
A exceção acima verifica primeiro se há um NameError no bloco try . Em seguida, ele imprime a exceção padrão NameError primeiro ("nome 'B' não está definido"). E suporta isso com sua exceção escrita ("B precisa ser definido, por favor").
E se você quiser lidar com uma cadeia de exceções, também pode acompanhar um bloco try com muitas instruções except . Isso é muito útil se o seu bloco try tiver o potencial de ter muitas exceções:
try:
B = 5
C = 2 + B
D = float(6)
F = 7/0
except NameError as err:
print(err,":", "B needs to be defined, please")
except ValueError as val:
print(val,":", "You can't convert that data")
except ZeroDivisionError as zeroerr:
print(zeroerr,":", "You can't divide a number by zero")
else:
print(u"Operation successfull! The results are: %s, %s, and %s"%(C, D, F))
Output: division by zero : You can't divide a number by zero
E se a divisão for válida? Por exemplo, substituir F = 7/0 no código acima por F = 7/5 dá:
Output: Operation successfull! The results are: 7, 6.0, and 1.4
Exceções definidas pelo usuário em Python
Você também pode criar sua exceção e chamá-los posteriormente em seu programa. Isso permite fornecer uma descrição específica de sua exceção e nomeá-la como quiser.
No entanto, todas as exceções definidas pelo usuário (direta ou indiretamente) ainda vêm da classe interna Exception do Python.
O código de exemplo abaixo faz referência à Exceção de base diretamente chamando RuntimeError a partir dela:
class connectionError(RuntimeError):
def __init__(self, value):
self.value = value
try:
raise connectionError("Bad hostname")
except connectionError as err:
print(err.value)
Output: Bad hostname
Observe que connectionError , neste caso, é uma classe definida pelo usuário, que você pode aumentar a qualquer momento que precisar em seu programa.
Você pode fazer uma exceção definida pelo usuário derivando-a diretamente da classe base Exception . A exceção abaixo, no entanto, evita a subtração de 5 de 6 e chama a exceção da classe base diretamente:
class errors(Exception):
pass
class sixFiveError(errors):
def __init__(self, value, message):
self.value = value
self.message = message
try:
raise sixFiveError(6-5,"This substraction is not allowed")
except sixFiveError as e:
print("There was an error:", e.message)
Output: There was an error: This substraction is not allowed
Na prática, você pode usar uma exceção definida anteriormente chamando-a em outra função. Por exemplo, você pode criar um floatError que permite apenas a adição de dois flutuadores:
# First call the base exception classes:
class errors(Exception):
pass
# Next, derive your own exception from the base class:
class FloatError(errors):
def __init__(self, value, message):
self.value = value
self.message = message
# Create a function to add two floats:
def addTwoFloat(a, b):
if (type(a) and type(b)) != float:
raise FloatError(a+b,"Numbers must be float to add")
else:
print(a + b)
addTwoFloat(4, 7)
Output: __main__.FloatError: (11, 'Numbers must be float to add')
Como agora você definiu uma classe FloatError , o Python a levanta se você tentar adicionar dois literais não flutuantes usando a função addtwoFloat .
Você pode imprimir a classe FloatError no mesmo arquivo Python onde a criou para ver o que acontece:
print(FloatError)
Output: <class '__main__.FloatError'>
FloatError , no entanto, não é uma exceção embutida do Python. Você pode verificar isso chamando FloatError em outro arquivo Python novo onde você não criou esta classe:
print(FloatError)
Output: NameError: name 'FloatError' is not defined
Você obtém um NameError porque o Python não o reconhece como uma exceção padrão.
Você também pode tentar autodefinir outras classes de erro para ver como elas funcionam.
Torne seus programas Python mais amigáveis ao usuário com exceções
Existem muitas exceções padrão em Python. Mas você também pode definir o seu. No entanto, a facilidade de uso do seu programa depende, até certo ponto, de como ele lida com várias exceções (sejam definidas pelo usuário, não específicas ou padrão).
As exceções, entretanto, permitem que você determine como seu programa deve funcionar quando os usuários interagem com eles. Declarar de forma clara e concisa a causa de um erro também informa aos usuários o que estão fazendo de errado e, às vezes, os aponta na direção certa.