"Si un ouvrier veut bien faire son travail, il doit d'abord affûter ses outils." - Confucius, "Les Entretiens de Confucius. Lu Linggong"
Page de garde > La programmation > bugs Python auxquels chaque développeur est encore confronté et comment les corriger)

bugs Python auxquels chaque développeur est encore confronté et comment les corriger)

Publié le 2024-10-31
Parcourir:502

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

Écrit par Rupesh Sharma AKA @hackyrupesh

Python, avec sa simplicité et sa beauté, est l'un des langages de programmation les plus populaires au monde. Cependant, même en 2024, certaines failles continuent de gêner les développeurs. Ces problèmes ne sont pas toujours dus à des faiblesses de Python, mais plutôt à sa conception, à son comportement ou à des idées fausses courantes qui entraînent des résultats inattendus. Dans cet article de blog, nous examinerons les 5 principaux problèmes Python que chaque développeur rencontre encore en 2024, ainsi que leurs solutions.


1. Arguments par défaut mutables : un piège silencieux

Le problème

L'un des bogues Python les plus tristement célèbres est l'argument par défaut mutable. Lorsqu'un objet mutable (comme une liste ou un dictionnaire) est utilisé comme argument par défaut dans une fonction, Python n'évalue cet argument par défaut qu'une seule fois lorsque la fonction est définie, et non à chaque fois que la fonction est appelée. Cela conduit à un comportement inattendu lorsque la fonction modifie l'objet.

Exemple

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 solution

Pour éviter cela, utilisez Aucun comme argument par défaut et créez une nouvelle liste dans la fonction si nécessaire.

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]

Références

  • L'argument par défaut de Python a eu un piège

2. L'erreur de clé insaisissable dans les dictionnaires

Le problème

KeyError se produit lors de la tentative d'accès à une clé de dictionnaire qui n'existe pas. Cela peut être particulièrement délicat lorsque vous travaillez avec des dictionnaires imbriqués ou lorsque vous traitez des données dont la structure n'est pas garantie.

Exemple

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

La solution

Pour éviter KeyError, utilisez la méthode get(), qui renvoie None (ou une valeur par défaut spécifiée) si la clé n'est pas trouvée.

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

Pour les dictionnaires imbriqués, pensez à utiliser le defaultdict du module de collections ou des bibliothèques comme dotmap ou pydash.

from collections import defaultdict

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

Références

  • Python KeyError et comment le gérer

3. Erreurs silencieuses avec tentative d'utilisation excessive

Le problème

Une utilisation excessive ou abusive des blocs try-sauf peut conduire à des erreurs silencieuses, où les exceptions sont interceptées mais ne sont pas correctement gérées. Cela peut rendre les bugs difficiles à détecter et à déboguer.

Exemple

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

Dans l'exemple ci-dessus, l'erreur ZeroDivisionError est détectée et ignorée, mais cela peut masquer le problème sous-jacent.

La solution

Spécifiez toujours le type d'exception que vous interceptez et gérez-le de manière appropriée. La journalisation de l'erreur peut également aider à détecter les problèmes.

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

Pour une gestion plus large des exceptions, vous pouvez utiliser la journalisation au lieu de pass :

import logging

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

Références

  • Les meilleures pratiques d'essai de Python

4. Division entière : le piège de la troncature

Le problème

Avant Python 3, la division de deux entiers effectuait une division au sol par défaut, tronquant le résultat en un entier. Bien que Python 3 ait résolu ce problème avec une véritable division (/), certains développeurs sont toujours confrontés à des problèmes lorsqu'ils utilisent involontairement la division d'étage (//).

Exemple

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

La solution

Utilisez toujours / pour la division, sauf si vous avez spécifiquement besoin d'une division d'étage. Soyez prudent lorsque vous portez du code de Python 2 vers Python 3.

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

Pour un code clair et prévisible, envisagez d'utiliser decimal.Decimal pour des opérations arithmétiques plus précises, en particulier dans les calculs financiers.

from decimal import Decimal

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

Références

  • Division Python : /vs //

5. Fuites de mémoire avec références circulaires

Le problème

Le garbage collector de Python gère l'essentiel de la gestion de la mémoire, mais les références circulaires peuvent provoquer des fuites de mémoire si elles ne sont pas gérées correctement. Lorsque deux objets ou plus se référencent mutuellement, ils peuvent ne jamais être récupérés, ce qui entraîne une utilisation accrue de la mémoire.

Exemple

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 solution

Pour éviter les références circulaires, pensez à utiliser des références faibles via le module lowref, qui permet de récupérer les références lorsqu'aucune référence forte n'existe.

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

Vous pouvez également interrompre manuellement le cycle en définissant les références sur Aucune avant de supprimer les objets.

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

Références

  • Gestion de la mémoire Python et récupération de place

Conclusion

Même en 2024, les développeurs Python continuent de rencontrer ces bugs courants. Bien que le langage ait évolué et amélioré au fil des années, ces problèmes sont souvent liés à des aspects fondamentaux du fonctionnement de Python. En comprenant ces pièges et en appliquant les solutions appropriées, vous pouvez écrire un code plus robuste et sans erreur. Bon codage !


Écrit par Rupesh Sharma AKA @hackyrupesh

Déclaration de sortie Cet article est reproduit sur : https://dev.to/hackyrupesh/5-python-bugs-that-every-developer-is-still-facing-in-2024-and-how-to-fix-them-5f4p? 1 comme s'il y a une infraction, veuillez contacter [email protected] pour la supprimer.
Dernier tutoriel Plus>

Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.

Copyright© 2022 湘ICP备2022001581号-3