"Si un trabajador quiere hacer bien su trabajo, primero debe afilar sus herramientas." - Confucio, "Las Analectas de Confucio. Lu Linggong"
Página delantera > Programación > Errores de Python a los que se enfrentan todos los desarrolladores y cómo solucionarlos)

Errores de Python a los que se enfrentan todos los desarrolladores y cómo solucionarlos)

Publicado el 2024-10-31
Navegar:479

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

Escrito por Rupesh Sharma también conocido como @hackyrupesh

Python, con su simplicidad y belleza, es uno de los lenguajes de programación más populares del mundo. Sin embargo, incluso en 2024, ciertas fallas continúan preocupando a los desarrolladores. Estos problemas no siempre se deben a debilidades de Python, sino a su diseño, comportamiento o conceptos erróneos comunes que dan lugar a resultados imprevistos. En este artículo de blog, analizaremos los cinco problemas principales de Python que todo desarrollador seguirá encontrando en 2024, así como sus soluciones.


1. Argumentos predeterminados mutables: una trampa silenciosa

El problema

Uno de los errores más notorios de Python es el argumento predeterminado mutable. Cuando un objeto mutable (como una lista o un diccionario) se usa como argumento predeterminado en una función, Python solo evalúa este argumento predeterminado una vez cuando se define la función, no cada vez que se llama a la función. Esto genera un comportamiento inesperado cuando la función modifica el objeto.

Ejemplo

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!

La solución

Para evitar esto, use Ninguno como argumento predeterminado y cree una nueva lista dentro de la función si es necesario.

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]

Referencias

  • El argumento predeterminado de Python te pilló

2. El escurridizo error clave en los diccionarios

El problema

Se produce un error de clave al intentar acceder a una clave de diccionario que no existe. Esto puede resultar especialmente complicado cuando se trabaja con diccionarios anidados o cuando se trata de datos cuya estructura no está garantizada.

Ejemplo

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

La solución

Para evitar KeyError, utilice el método get(), que devuelve Ninguno (o un valor predeterminado especificado) si no se encuentra la clave.

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

Para diccionarios anidados, considere usar defaultdict del módulo de colecciones o bibliotecas como dotmap o pydash.

from collections import defaultdict

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

Referencias

  • Python KeyError y cómo manejarlo

3. Errores silenciosos con uso excesivo de prueba-excepto

El problema

El uso excesivo o incorrecto de los bloques try-except puede provocar errores silenciosos, en los que las excepciones se detectan pero no se manejan adecuadamente. Esto puede dificultar la detección y depuración de errores.

Ejemplo

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

En el ejemplo anterior, ZeroDivisionError se detecta y se ignora, pero esto puede enmascarar el problema subyacente.

La solución

Especifique siempre el tipo de excepción que está detectando y manéjelo adecuadamente. Registrar el error también puede ayudar a localizar problemas.

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

Para un manejo de excepciones más amplio, puedes usar el registro en lugar de pasar:

import logging

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

Referencias

  • Mejores prácticas de prueba-excepto de Python

4. División entera: la trampa del truncamiento

El problema

Antes de Python 3, la división de dos números enteros realizaba una división de piso de forma predeterminada, truncando el resultado a un número entero. Aunque Python 3 resolvió esto con la división verdadera (/), algunos desarrolladores aún enfrentan problemas cuando usan involuntariamente la división de piso (//).

Ejemplo

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

La solución

Utilice siempre / para dividir a menos que necesite específicamente una división del piso. Tenga cuidado al migrar código de Python 2 a Python 3.

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

Para obtener un código claro y predecible, considere usar decimal.Decimal para operaciones aritméticas más precisas, especialmente en cálculos financieros.

from decimal import Decimal

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

Referencias

  • División Python: / vs //

5. Pérdidas de memoria con referencias circulares

El problema

El recolector de basura de Python maneja la mayor parte de la administración de memoria, pero las referencias circulares pueden causar pérdidas de memoria si no se manejan correctamente. Cuando dos o más objetos hacen referencia entre sí, es posible que nunca se recolecten basura, lo que genera un mayor uso de memoria.

Ejemplo

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

La solución

Para evitar referencias circulares, considere usar referencias débiles a través del módulo débilref, que permite que las referencias se recopilen como basura cuando no existen referencias fuertes.

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, puedes romper el ciclo manualmente estableciendo referencias en Ninguno antes de eliminar los objetos.

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

Referencias

  • Gestión de memoria y recolección de basura de Python

Conclusión

Incluso en 2024, los desarrolladores de Python continúan encontrando estos errores comunes. Si bien el lenguaje ha evolucionado y mejorado a lo largo de los años, estos problemas suelen estar relacionados con aspectos fundamentales de cómo funciona Python. Al comprender estos obstáculos y aplicar las soluciones adecuadas, podrá escribir un código más sólido y sin errores. ¡Feliz codificación!


Escrito por Rupesh Sharma, también conocido como @hackyrupesh

Declaración de liberación Este artículo se reproduce en: https://dev.to/hackyrupesh/5-python-bugs-that-every-developer-is-still-facing-in-2024-and-how-to-fix-them-5f4p? 1 como Si hay alguna infracción, comuníquese con [email protected] para eliminarla.
Último tutorial Más>

Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.

Copyright© 2022 湘ICP备2022001581号-3