Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Industrial programming >> python

Como não lidar com exceções em Python


Eu vejo muitas pessoas lidando com exceções da maneira errada. Talvez isso se aplique a você também. A situação a seguir soa familiar?

Você está escrevendo algum código, mas sabe que a biblioteca que está usando pode gerar uma exceção. Você não se lembra qual, exatamente. Neste ponto, é tentador usar os chamados blocos catch-all e continuar com as coisas divertidas.

Índice

A pior maneira de fazer isso


O pior que você pode fazer é criar um bloco try-except que capture qualquer coisa. Por catch-all, quero dizer algo como:
try:
    ...
except:
    pass

Blocos catch-all como esses são ruins porque:
  1. Você não tem ideia de quais outras exceções podem ser levantadas (mais sobre isso mais tarde).
  2. Estamos ocultando a exceção usando a passagem silenciosamente em vez de registrar o erro.

Além disso, um except vazio pegará tudo, incluindo KeyboardInterrupt (controle + c), SystemExit , e até NameErrors ! Isso significa que o código a seguir não pode ser interrompido de forma limpa:
from time import sleep

while True:
    try:
        print("Try and stop me")
        sleep(1)
    except:
        print("Don't.. stop.. me now!")

Sinta-se à vontade para experimentá-lo. Você precisa fechar a janela do terminal ou matar o processo Python para parar este programa.

Uma maneira um pouco melhor de capturar todas as exceções


Por outro lado, ao usar except Exception , embora ainda seja uma maneira rápida e suja de capturar muitas exceções, pelo menos você poderá interromper o processo em execução corretamente:
from time import sleep
while True:
    try:
        print("Try and stop me")
        sleep(1)
    except Exception:
        print("Ok I'll stop!")

Ao capturar Exception você não pegará SystemExit , KeyboardInterrupt e outras exceções semelhantes. Por que isso, você pergunta?

Todas as exceções herdam de uma classe chamada BaseException . De acordo com a documentação oficial:“Em um try instrução com um except cláusula que menciona uma classe específica, essa cláusula também trata de quaisquer classes de exceção derivadas dessa classe.” Um except vazio é equivalente a except BaseException , portanto, ele capturará todas as exceções possíveis.

Por outro lado, a classe Exception é definido como:“Todas as exceções internas que não saem do sistema são derivadas desta classe. Todas as exceções definidas pelo usuário também devem ser derivadas desta classe.”

Fica ainda pior


No exemplo a seguir, usamos a biblioteca os para obter o diretório de trabalho atual. No entanto, meus dedinhos gordos cometeram um erro de digitação:
import os
try:
    working_dir = os.getcdw()
    print(working_dir)
except:
    print('error')

Porque os.getcdw não é uma função no módulo os, um NameError é lançado. Em vez de falhar, a cláusula except detectará o erro, imprimirá 'erro' e o programa continuará apesar de nosso erro de digitação flagrante. Infelizmente, este não pode ser resolvido capturando Exception qualquer!

Aparentemente, nosso pequeno truque do primeiro passo não é uma solução para todos os nossos problemas. Então, o que deve nós fazemos?

Pegue o que você pode manipular


Uma frase que muitas vezes é ouvida sobre exceções é:pegue o que você pode manipular . Muitos desenvolvedores são tentados a lidar diretamente com exceções, embora muitas vezes seja melhor deixar a exceção se propagar para uma parte do seu programa que possa realmente lidar com ela.

Por exemplo, considere a parte de um editor de texto que abre e carrega arquivos, vamos chamá-la de OpenFile classe. Se o usuário solicitou a abertura de um arquivo que não existe, você pode manipular diretamente esse erro ou deixá-lo se propagar.

Nesse caso, é melhor propagar a exceção para o chamador, porque OpenFile não tem ideia de quão ruim é essa exceção para o chamador. O chamador pode lidar com a situação de várias maneiras:

De qualquer forma, não depende do OpenFile class para decidir o que fazer no caso de um FileNotFoundError .

Então, uma exceção deve sempre ser propagada? Não. Uma possível exceção que pode ser tratada na classe FileOpen é a TimeoutError . Você pode tentar novamente algumas vezes, por exemplo, sem incomodar o chamador com o erro. Esta é uma exceção que OpenFile pode lidar, então não há problema em pegá-lo e tentar novamente.

Conclusão


Você não deve, sob nenhuma circunstância, capturar mais exceções do que pode manipular. Blanket exceto blocos são uma receita para bugs e código imprevisível. Em outras palavras:pegue o que você pode manipular.

Se você escrever seu código com a matra 'pegue o que você pode manipular' em mente, escrever blocos pega-tudo está quebrando todas as regras. Então, por favor, pare de fazer isso. Como exercício, você pode revisitar alguns de seus códigos existentes e ver se eles podem ser melhorados com esse novo conhecimento!

python

  1. Operadores Python
  2. Erros do Python e exceções incorporadas
  3. Exceções personalizadas do Python
  4. Como obter data e hora atuais em Python?
  5. Java captura múltiplas exceções
  6. Como não ser péssimo em ensinar um novo software
  7. Instrução Python Print():Como imprimir com exemplos
  8. Python Dictionary Append:Como adicionar um par de chave/valor
  9. Python New Line:Como imprimir SEM Newline em Python
  10. Python Average:Como encontrar a AVERAGE de uma lista em Python