Como escrever códigos Python mais robustos?
Quem nunca escreveu um código que funcionou lindamente no ambiente local, mas foi um desastre em outros sistemas? Uma das razões principais para esse tipo de ocorrência é a falta de tratamento adequado de erros e verificações de robustez. Neste post, exploraremos algumas práticas recomendadas para escrever códigos Python mais robustos a partir de tratamento de erros.
Verificações de entradas
Um problema bem comum: você fez uma função que recebe inteiros como entrada e seu usuário escreve uma string. Esse tipo de erro pode ser facilmente evitado com a verificação do input do usuário. Portanto, antes mesmo de sua função começar a ser executada, é essencial validar as entradas. Ao verificar os tipos e valores de suas entradas, você pode evitar comportamentos inesperados ou falhas. Veja um exemplo:
def diga_oi(nome: str) -> None:
if not isinstance(nome, str):# verifica se a entrada é do tipo correto (string)
raise TypeError("O nome deve ser uma string")
print(f"Olá, {nome}!")
# Teste da função com uma entrada válida
diga_oi("João") # Resultado: Olá, João!
# Teste da função com uma entrada inválida
try:
diga_oi(123)
except TypeError as e:
print(e) # Resultado: O nome deve ser uma string
Neste trecho, verificamos explicitamente na função se a entrada tem o tipo correto (str no exemplo). No caso de exceção, informamos o usuário sobre o erro ocorrido sem travar o programa.
Note que a função definida acima possui um argumento definido assim: (nome: str). Isso é uma dica de tipo para o parâmetro de função. Ela torna os códigos mais compreensíveis para desenvolvedores. As dicas de tipo em Python deixam claro que tipo de dados a função espera.
Na função mostrada acima, também definimos uma mensagem de erro bem clara que informa ao usuário exatamente o erro ocorrido. Fornecer mensagens de erro claras é essencial para auxiliar os usuários a entender o que deu errado.
O trecho mostrado também usa um bloco try/except para testar a entrada do usuário e imprimir uma exceção prevenindo a quebra da função. Com ele, lidamos com exceções sem quebrar os códigos.
Blocos try/except
No exemplo acima, já fizemos uso de um bloco try/except. Esses blocos permitem capturar e lidar com exceções que podem ocorrer durante a execução de nossos códigos. Eles são uma das principais ferramentas para garantir códigos robustos e que não quebram com erros inesperados. No caso ilustrativo abaixo, o bloco try/except foi usado para lidar com a possibilidade de um usuário tentar realizar uma divisão por zero inadvertidamente:
def divide(a: float, b: float) -> float:
try:
return a / b
except ZeroDivisionError as e:
return f"Não é possível dividir por zero! {e}"
# Teste da função com uma entrada inválida
print(divide(10, 2)) # Resultado: 5.0
# Teste da função com uma entrada inválida
print(divide(10, 0)) # Resultado: Não é possível dividir por zero! division by zero
Neste trecho, se um usuário tentar realizar uma divisão por zero, ele receberá uma mensagem informativa ao invés de travar o programa.
Registros de erros (logging)
Em muitos casos, além de blocos try/except, precisamos registrar erros ou exceções de uma maneira mais estruturada. O módulo de logging (registro integrado) do Python facilita isso. Veja um exemplo ilustrativo de como usá-lo modificando o código mostrado acima:
import logging # linha nova
# Configura o registro de erros (logging)
logging.basicConfig(level=logging.ERROR) # linha nova
def divide(a: float, b: float) -> float:
try:
return a / b
except ZeroDivisionError as e:
logging.error(f"Não é possível dividir por zero! {e}") # linha nova
return f"Não é possível dividir por zero! {e}"
# Teste da função com uma entrada inválida
print(divide(10, 2)) # Resultado: 5.0
# Teste da função com uma entrada inválida
print(divide(10, 0)) # Resultado: Não é possível dividir por zero! division by zero
# Resultado do logging: ERROR:root:Não é possível dividir por zero! division by zero
Neste exemplo, além de imprimir a mensagem de erro para o usuário, registramos o tipo de erro ocorrido. Esse tipo de registro ajuda na depuração de códigos e no planejamento de modificações para torná-los mais robustos.
Conclusões
Para escrever códigos Python mais robustos, seguir algumas práticas simples faz toda a diferença. Portanto, sempre valide as entradas antes de executar suas funções. Use blocos try/except para capturar exceções que podem ocorrer durante a execução de seus programas. Registre os erros de log usando o módulo logging integrado do Python para aprimorar sua capacidade de depuração.
Veja também:
Concatenações com join() para strings em Python
O que é operador ternário em Python?
F-strings em Strings Multilinhas
Decodificação de strings em Python com decode()
Métodos para Manipular Strings em Python
Módulo Getpass para Prompts de Senhas
Aprenda a comparar textos com Python com Difflib
Módulo textwrap para formatação de textos
Manipulação de arquivos com Python
os.environ: gerenciamento de variáveis de ambiente com Python
Métodos Avançados Do Módulo os
Aprenda a criar documentos do Word com Python
Três dicas simples para escrever códigos Python mais robustos
Encontrou algum erro ou quer fazer uma sugestão? Por favor, entre em contato usando nosso formulário de contatos.