Erros comuns em Python: Guia completo para resolvê-los

No percurso de um programador, é inevitável cruzar com erros durante o desenvolvimento de software. Estes podem manifestar-se de diversas formas, desde falhas na lógica que resultam em comportamentos inesperados, infrações das regras de uma linguagem de programação, até problemas que emergem durante a execução do programa, entre muitos outros. Esses erros são comumente conhecidos como bugs.

Os bugs são uma constante em todas as linguagens de programação, independentemente da sua simplicidade ou facilidade de uso.

Em Python, por exemplo, embora a linguagem se destaque pela sua legibilidade, siga uma sintaxe expressiva e seja considerada relativamente acessível em comparação com outras linguagens, a possibilidade de encontrar erros de programação ainda é real.

Dado que os erros podem surgir, uma estratégia eficaz é familiarizar-se com os diferentes tipos de erros que podem ocorrer e as suas causas. Isso permite prevenir ou minimizar esses erros ao programar, bem como saber como abordá-los quando surgem.

A seguir, apresentamos alguns dos erros comuns em Python que você pode encontrar ao programar:

Erros de Sintaxe

Um erro de sintaxe ocorre quando o código escrito viola as regras da linguagem de programação. Isso resulta em uma linha de código inválida.

Em Python, por exemplo, ao imprimir uma string, esta deve estar entre aspas. Omissão resulta em um erro de sintaxe.

Outros erros de sintaxe incluem a falta de abertura ou fechamento de parênteses, colchetes ou chaves, palavras-chave ou nomes de função incorretos, dois pontos ausentes no final das instruções de controle de fluxo, ou a omissão de operadores obrigatórios em expressões.

Em geral, erros de sintaxe surgem da violação de uma regra da sintaxe da linguagem Python.

    ## erro de sintaxe devido a falta de aspas
    print("Olá Mundo)
    
    idade = 20
    ## erro de sintaxe devido a falta de dois pontos numa declaração if
    if idade > 18
        print("A idade é superior a 18")
    
    ## erro de sintaxe porque '(' nunca foi fechado
    def quadrado(x:
        return x * x
    print(quadrado(4))
  

Ao executar o código acima, você irá encontrar uma mensagem de erro semelhante à seguinte:

A mensagem de erro ao executar o código é a seguinte:

    File "/home/madici/Desktop/helloworld.py", line 1
    print("Olá Mundo)
          ^
    SyntaxError: string literal não terminado (detectado na linha 1)
  

Para resolver estes erros, utilize a sintaxe correta do Python, como demonstrado abaixo:

  print("Olá Mundo")
  
  idade = 20
  if idade > 18:
    print("A idade é superior a 18")
  
  def quadrado(x):
    return x * x
  print(quadrado(4))
  

IndentationError

Ao contrário de linguagens como Java, C ou C++, que usam chaves para delimitar blocos de código, Python utiliza a indentação para definir a hierarquia e estrutura dos blocos. Por exemplo, em Java, o código a ser executado após a avaliação de uma condição é incluído entre chaves.

Em Python, no entanto, o bloco de código é recuado. Um recuo típico em Python consiste em quatro espaços ou uma tabulação. No entanto, o número de espaços não importa, desde que seja consistente em todo o código.

Como programador Python, é provável que encontre erros de indentação ao omitir a indentação necessária, ao escrever instruções de controle ou funções, ao misturar tabulações e espaços, pois isso confunde o interpretador, ao inserir indentação no lugar errado ou quando os recuos não são consistentes em todo o seu código.

Um exemplo de código que causa um erro de recuo é mostrado abaixo:

  idade = 20
  if idade > 18:
  print("A idade é superior a 18")
    print("Pode conduzir")
  else:
    print("A idade é inferior a 18")
  

As mensagens de erro resultantes do código acima são mostradas abaixo:

A mensagem de erro ao executar o código é a seguinte:

    File "/home/madici/Desktop/helloworld.py", line 3
    print("A idade é superior a 18")
    ^
  IndentationError: esperado um bloco indentado após a declaração 'if' na linha 2
  

Para corrigir os erros, é preciso recuar a linha após a declaração if e assegurar que o recuo corresponde ao restante do código, como mostrado abaixo:

  idade = 20
  if idade > 18:
    print("A idade é superior a 18")
    print("Pode conduzir")
  else:
    print("A idade é inferior a 18")
  

TypeError

Em Python, um TypeError é uma exceção que ocorre ao tentar executar uma operação utilizando um tipo de dado incompatível. Por exemplo, ao tentar somar uma string e um inteiro, ou concatenar uma string com um inteiro, um TypeError é gerado.

TypeErrors também podem surgir ao usar funções ou métodos com tipos de dados incorretos, ao usar um índice não inteiro para aceder a elementos de uma sequência, como uma lista, ou ao tentar iterar por um objeto que não é iterável.

De forma geral, qualquer operação que envolva tipos de dados incorretos resultará num TypeError.

Exemplos de operações que podem originar TypeErrors são apresentados abaixo:

    # TypeError resultante da concatenação de uma string com um inteiro
    idade = 25
    mensagem = "Tenho " + idade + " anos."
    
    
    lista1 = [1, "olá", 5, "mundo", 18, 2021]
    #TypeErrors resultantes do uso incorreto de métodos internos
    print(sum(lista1))
    
    #TypeError resultante da soma de uma string e um inteiro
    num1 = 10
    num2 = "16"
    print(num1 + num2)
    
    #TypeError resultante da utilização de um índice não inteiro
    lista2 = ["olá", "de", "outro", "lugar"]
    print(lista2["1"])
  

As mensagens de erro resultantes do código acima são mostradas abaixo:

Um exemplo de mensagem TypeError do código é mostrado abaixo:

    File "/home/madici/Desktop/helloworld.py", line 3, in <module>
    mensagem = "Tenho " + idade + " anos."
              ~~~~~~~~^~~~~
    TypeError: só é possível concatenar str (não "int") com str
  

Para resolver os erros, use os tipos de dados corretos ou faça conversões de tipo, como mostrado abaixo:

    idade = 25
    mensagem = "Tenho " + str(idade) + " anos."
    
    lista1 = [1, 5, 18, 2021]
    print(sum(lista1))
    
    num1 = 10
    num2 = "16"
    print(num1 + int(num2))
    
    lista2 = ["olá", "de", "outro", "lugar"]
    print(lista2[1])
  

AttributeError

Em Python, um AttributeError ocorre quando se tenta utilizar um atributo inexistente num objeto ou quando se chama um método que não existe no objeto. Um AttributeError indica que um objeto não possui o atributo ou método que está sendo invocado.

Por exemplo, se tentar invocar um método de string num inteiro, irá encontrar um AttributeError, pois esse método não existe no tipo de objeto que está a invocar.

No exemplo mostrado abaixo, o método capitalize(), utilizado para converter a primeira letra de uma string para maiúscula, está sendo invocado num inteiro. Isso resulta num erro de atributo porque int não tem o método capitalize().

    # AttributeError resultante da invocação de capitalize() num valor int
    num = 1445
    cap = num.capitalize()
    print(cap)
  

A execução deste código resulta na seguinte mensagem de erro:

A mensagem AttributeError do código é a seguinte:

    File "/home/madici/Desktop/helloworld.py", line 3, in <module>
    cap = num.capitalize()
          ^^^^^^^^^^^^^^
    AttributeError: o objeto 'int' não tem o atributo 'capitalize'
  

Para resolver um AttributeError, assegure-se de que o método ou atributo invocado existe no objeto correspondente. Neste caso, invocar capitalize() num tipo de dado string resolve este erro, como mostrado abaixo:

ImportError

O ImportError em Python surge quando se tenta importar um módulo que não é encontrado ou que não está acessível no ambiente atual. Este pode não estar instalado, o caminho pode estar configurado de forma incorreta ou o nome do módulo pode estar incorreto.

Um ImportError tem uma subclasse específica chamada ModuleNotFoundError, que é o erro gerado quando se tenta importar um módulo que não pode ser encontrado.

Por exemplo, o código abaixo, que tenta importar o pandas da biblioteca de análise de dados, gera este erro porque o módulo não está instalado.

A mensagem de ImportError gerada é mostrada abaixo:

    File "/home/madici/Desktop/helloworld.py", line 1, in <module>
    import pandas
    ModuleNotFoundError: Não existe nenhum módulo com o nome 'pandas'
  

Para resolver este erro, verifique se os módulos que está a tentar importar foram instalados. Se isso não resolver o problema, verifique se está a usar a grafia correta do módulo e o caminho correto do arquivo para aceder ao módulo.

ValueError

Esta é uma exceção que ocorre quando uma função em Python recebe um valor do tipo de dado correto, mas o valor é inadequado. Por exemplo, a função Math.sqrt() usada para encontrar a raiz quadrada de valores numéricos retornará um ValueError se um número negativo for passado como argumento.

Embora o valor seja do tipo correto, ou seja, um valor numérico, ser negativo torna-o inadequado para a função.

A função int() que converte um número ou string retornará um ValueError se passar uma string que não seja um valor string numérico. Passar “123” ou “45” para a função não retorna erro, pois as strings podem ser convertidas para o valor inteiro apropriado.

No entanto, se passar uma string que não seja um valor string numérico, como “Olá”, será retornado um ValueError. Isto porque, apesar de “Olá” ser uma string, não possui um equivalente inteiro.

Um exemplo de código que gera um ValueError é apresentado abaixo:

    # Value error resultante de um valor int inadequado em sqrt()
    import math
    num = -64
    raiz = math.sqrt(num)
    print(raiz)
    
    # Value error resultante da passagem de uma string sem equivalente inteiro para a função int()
    numString = "Olá"
    num = int(numString)
    print(num)
  

Os erros do código acima são mostrados abaixo:

A mensagem de erro gerada é a seguinte:

    File "/home/madici/Desktop/helloworld.py", line 4, in <module>
    raiz = math.sqrt(num)
          ^^^^^^^^^^^^^^
    ValueError: erro de domínio matemático
  

Para corrigir o erro, utilize os valores apropriados nas funções, como mostrado abaixo:

    import math
    num = 64
    raiz = math.sqrt(num)
    print(raiz)
    
    numString = "5231"
    num = int(numString)
    print(num)
  

IOError

O IOError (Erro de Entrada/Saída) é uma exceção que ocorre quando uma operação de entrada ou saída falha. Isso pode ser causado por tentar aceder a um ficheiro inexistente, falta de espaço em disco, tentar aceder a um ficheiro para o qual não tem permissões, ou quando o ficheiro está a ser usado por outras operações.

Métodos como open(), read(), write() e close(), usados ao manipular ficheiros, são os que mais provavelmente causam esse erro.

Considere o código abaixo que tenta abrir um ficheiro chamado “notas.txt” que não existe. O código resulta em um IOError que gera o FileNotFoundError:

Com a seguinte mensagem de erro:

    File "/home/madici/Desktop/helloworld.py", line 2, in <module>
    file1 = open("notas.txt", "r")
            ^^^^^^^^^^^^^^^^^^^^^^
    FileNotFoundError: [Errno 2] Não existe nenhum ficheiro ou diretório: 'notas.txt'
  

Para evitar o erro acima, basta assegurar que o ficheiro “notas.txt” existe no diretório em que está a executar o terminal. Outra forma de tratar IOError é usar o bloco try except, como mostrado abaixo:

NameError

O NameError é uma exceção que surge quando tenta utilizar uma variável, função ou módulo que não existe, não está definido no âmbito atual, ou não recebeu um valor.

Este erro ocorre geralmente quando digita nomes de variáveis ou funções incorretamente, ou as usa antes de serem definidas. Usar um módulo sem importá-lo também resulta num NameError.

O código seguinte resulta numa exceção NameError:

    # name error ocorre porque o módulo math não foi importado
    num = 64
    raiz = math.sqrt(64)
    print(raiz)
    
    # NameError ocorre porque x é usado antes de ser definido
    y = 23
    print(x)
    
    #NameEror porque o nome da função não está definido
    def cumprimentar():
        print("Bom dia")
    cumprimenta() #NameError: nome 'cumprimenta' não está definido
  

As seguintes mensagens de erro resultam do código acima:

Um exemplo de mensagem NameError é mostrado abaixo:

    File "/home/madici/Desktop/helloworld.py", line 3, in <module>
    raiz = math.sqrt(64)
           ^^^^
    NameError: o nome 'math' não está definido
  

Para resolver este NameError, verifique se não está a usar módulos antes de os importar, não está a usar variáveis ou funções antes de as definir e não está a digitar incorretamente nomes de funções ou variáveis:

    import math
    num = 64
    raiz = math.sqrt(64)
    print(raiz)
    
    y = 23
    print(y)
    
    def cumprimentar():
        print("Bom dia")
    cumprimentar()
  

IndexError

Um IndexError é uma exceção que ocorre quando tenta aceder a um índice numa lista ou tupla que está fora do intervalo. Considere a seguinte lista:

    lista1 = [1, 2, 3, 4, 5]
  

A lista tem cinco elementos. Em Python, os índices começam em 0 (zero). Portanto, a lista acima tem índices que variam de 0 a n-1, sendo n o número de elementos da lista. Neste caso, o índice da lista varia de 0 a 4.

Se tentar aceder a um elemento num índice superior a 4, irá encontrar um IndexError porque o índice está fora do intervalo da lista à qual está a tentar aceder. O código abaixo gera um IndexError:

    lista1 = [1, 2, 3, 4, 5]
    item = lista1[6] #IndexError porque o índice da lista está fora do intervalo
    print(item)
  

O erro do código é mostrado abaixo:

A mensagem IndexError gerada é a seguinte:

    File "/home/madici/Desktop/helloworld.py", line 2, in <module>
    item = lista1[6] #IndexError porque o índice da lista está fora do intervalo
           ~~~~~^^^
    IndexError: índice da lista fora do intervalo
  

A melhor forma de evitar um IndexError é usar as funções range() e len() para garantir que acede apenas a elementos dentro do intervalo, da seguinte forma:

    lista1 = [1, 2, 3, 4, 5]
    
    for i in range(len(lista1)):
        print(lista1[i])
  

KeyError

Um KeyError é uma exceção que ocorre quando tenta aceder a um elemento de um dicionário usando uma chave, e essa chave não é encontrada no dicionário. Considere o seguinte dicionário:

    cidades = {"Canadá": "Ottawa", "EUA": "Washington", "Itália": "Roma"}
  

As chaves no dicionário são “Canadá”, “EUA”, “Itália”. Pode aceder a elementos do dicionário de cidades usando estas chaves. No entanto, se tentar aceder a um elemento usando uma chave que não existe, como “Brasil”, irá encontrar um KeyError, como mostrado abaixo:

A mensagem KeyError gerada é mostrada abaixo:

    File "/home/madici/Desktop/helloworld.py", line 6, in <module>
    print(cidades["Brasil"])
          ~~~~~~^^^^^^^^^^
    KeyError: 'Brasil'
  

Para resolver um KeyError, verifique se as chaves que está a usar para aceder aos elementos de um dicionário estão efetivamente presentes no dicionário. Para fazer isso, pode usar uma declaração if…else como esta:

    cidades = {"Canadá": "Ottawa", "EUA": "Washington", "Itália": "Roma"}
    
    país = "Canadá"
    
    if país in cidades:
        print("A capital de " + país + " é " + cidades[país])
    else:
    print("A chave " + país + " não está presente no dicionário cidades")
  

Desta forma, irá evitar KeyErrors ao aceder a elementos de um dicionário

Conclusão

Ao programar em Python, independentemente do seu nível de especialização, é inevitável que se depare com erros. Portanto, assegure-se de se familiarizar com os diferentes tipos de erros abordados neste artigo, para garantir que estará apto a lidar com eles quando surgirem.

Pode também explorar alguns recursos úteis do Python para simplificar tarefas comuns.