"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > ython bugs que todo desenvolvedor ainda enfrenta e como corrigi-los)

ython bugs que todo desenvolvedor ainda enfrenta e como corrigi-los)

Publicado em 31/10/2024
Navegar:251

ython bugs that every developer is still facing in and how to fix them)

Escrito por Rupesh Sharma, também conhecido como @hackyrupesh

Python, com sua simplicidade e beleza, é uma das linguagens de programação mais populares do mundo. No entanto, mesmo em 2024, certas falhas continuam a incomodar os desenvolvedores. Esses problemas nem sempre se devem a fraquezas do Python, mas sim ao seu design, comportamento ou equívocos comuns que resultam em resultados imprevistos. Neste artigo do blog, veremos os 5 principais problemas do Python que todo desenvolvedor ainda encontrará em 2024, bem como suas soluções.


1. Argumentos padrão mutáveis: uma armadilha silenciosa

O problema

Um dos bugs mais infames do Python é o argumento padrão mutável. Quando um objeto mutável (como uma lista ou dicionário) é usado como argumento padrão em uma função, o Python avalia esse argumento padrão apenas uma vez quando a função é definida, não sempre que a função é chamada. Isso leva a um comportamento inesperado quando a função modifica o objeto.

Exemplo

def append_to_list(value, my_list=[]):
    my_list.append(value)
    return my_list

print(append_to_list(1))  # Outputs: [1]
print(append_to_list(2))  # Outputs: [1, 2] - Unexpected!
print(append_to_list(3))  # Outputs: [1, 2, 3] - Even more unexpected!

A solução

Para evitar isso, use None como argumento padrão e crie uma nova lista dentro da função, se necessário.

def append_to_list(value, my_list=None):
    if my_list is None:
        my_list = []
    my_list.append(value)
    return my_list

print(append_to_list(1))  # Outputs: [1]
print(append_to_list(2))  # Outputs: [2]
print(append_to_list(3))  # Outputs: [3]

Referências

  • Pegadinha do argumento padrão do Python

2. O Elusive KeyError nos dicionários

O problema

KeyError ocorre ao tentar acessar uma chave de dicionário que não existe. Isso pode ser especialmente complicado ao trabalhar com dicionários aninhados ou ao lidar com dados cuja estrutura não é garantida.

Exemplo

data = {'name': 'Alice'}
print(data['age'])  # Raises KeyError: 'age'

A solução

Para evitar KeyError, use o método get(), que retorna None (ou um valor padrão especificado) se a chave não for encontrada.

print(data.get('age'))  # Outputs: None
print(data.get('age', 'Unknown'))  # Outputs: Unknown

Para dicionários aninhados, considere usar o defaultdict do módulo de coleções ou bibliotecas como dotmap ou pydash.

from collections import defaultdict

nested_data = defaultdict(lambda: 'Unknown')
nested_data['name'] = 'Alice'
print(nested_data['age'])  # Outputs: Unknown

Referências

  • Python KeyError e como lidar com isso

3. Erros silenciosos com uso excessivo de try-except

O problema

O uso excessivo ou indevido de blocos try-except pode levar a erros silenciosos, onde as exceções são capturadas, mas não tratadas adequadamente. Isso pode dificultar a detecção e depuração de bugs.

Exemplo

try:
    result = 1 / 0
except:
    pass  # Silently ignores the error
print("Continuing execution...")

No exemplo acima, o ZeroDivisionError é capturado e ignorado, mas isso pode mascarar o problema subjacente.

A solução

Sempre especifique o tipo de exceção que você está capturando e trate-o adequadamente. Registrar o erro também pode ajudar a rastrear problemas.

try:
    result = 1 / 0
except ZeroDivisionError as e:
    print(f"Error: {e}")
print("Continuing execution...")

Para um tratamento de exceções mais amplo, você pode usar logging em vez de pass:

import logging

try:
    result = 1 / 0
except Exception as e:
    logging.error(f"Unexpected error: {e}")

Referências

  • Práticas recomendadas de teste exceto do Python

4. Divisão Inteira: A Armadilha do Truncamento

O problema

Antes do Python 3, a divisão de dois números inteiros realizava a divisão mínima por padrão, truncando o resultado para um número inteiro. Embora o Python 3 tenha resolvido isso com divisão verdadeira (/), alguns desenvolvedores ainda enfrentam problemas ao usar involuntariamente a divisão de piso (//).

Exemplo

print(5 / 2)  # Outputs: 2.5 in Python 3, but would be 2 in Python 2
print(5 // 2)  # Outputs: 2

A solução

Sempre use / para divisão, a menos que você precise especificamente de divisão de piso. Tenha cuidado ao portar código do Python 2 para o Python 3.

print(5 / 2)  # Outputs: 2.5
print(5 // 2)  # Outputs: 2

Para um código claro e previsível, considere usar decimal.Decimal para operações aritméticas mais precisas, especialmente em cálculos financeiros.

from decimal import Decimal

print(Decimal('5') / Decimal('2'))  # Outputs: 2.5

Referências

  • Divisão Python: / vs //

5. Vazamentos de memória com referências circulares

O problema

O coletor de lixo do Python lida com a maior parte do gerenciamento de memória, mas referências circulares podem causar vazamentos de memória se não forem tratadas corretamente. Quando dois ou mais objetos fazem referência um ao outro, eles nunca podem ser coletados como lixo, levando ao aumento do uso de memória.

Exemplo

Nó de classe
class Node:
    def __init__(self, value):
        self.value = value
        self.next = None

node1 = Node(1)
node2 = Node(2)
node1.next = node2
node2.next = node1  # Circular reference

del node1
del node2  # Memory not freed due to circular reference

A solução

Para evitar referências circulares, considere usar referências fracas por meio do módulo fracoref, que permite que as referências sejam coletadas como lixo quando não existem referências fortes.

import weakref

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None

node1 = Node(1)
node2 = Node(2)
node1.next = weakref.ref(node2)
node2.next = weakref.ref(node1)  # No circular reference now

Como alternativa, você pode interromper manualmente o ciclo definindo referências como None antes de excluir os objetos.

node1.next = None
node2.next = None
del node1
del node2  # Memory is freed

Referências

  • Gerenciamento de memória Python e coleta de lixo

Conclusão

Mesmo em 2024, os desenvolvedores Python continuam a encontrar esses bugs comuns. Embora a linguagem tenha evoluído e melhorado ao longo dos anos, essas questões estão frequentemente ligadas a aspectos fundamentais de como o Python funciona. Ao compreender essas armadilhas e aplicar as soluções apropriadas, você poderá escrever um código mais robusto e livre de erros. Boa codificação!


Escrito por Rupesh Sharma, também conhecido como @hackyrupesh

Declaração de lançamento Este artigo foi reproduzido em: https://dev.to/hackyrupesh/5-python-bugs-that-every-developer-is-still-facing-in-2024-and-how-to-fix-them-5f4p? 1, pois se houver alguma violação, entre em contato com [email protected] para excluí-la.
Tutorial mais recente Mais>

Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.

Copyright© 2022 湘ICP备2022001581号-3