Dans les premiers jours de travail en tant que programmeur Python, nous rencontrons tous différents types de bogues dans notre code, qui après quelques heures pénibles dans StackOverflow ne sont pas un bogue, mais des fonctionnalités Python. Vous trouverez ci-dessous les 5 erreurs les plus courantes commises par la plupart des nouveaux programmeurs Python. Découvrons-les un peu afin de gagner plusieurs heures en posant des questions sur les pages et les groupes sur Facebook.
1. Copiez des dictionnaires ou des listes
Lorsque vous devez faire une copie d'un dictionnaire ou d'une liste, il ne suffit pas d'utiliser simplement l'opérateur d'affectation.
Mauvais:>>> dict_a = {"name": "John", "address":"221B Baker street"} >>> dict_b = dict_a
Maintenant, si vous modifiez ou mettez à jour dict_b, alors dict_a sera également modifié - et tout cela grâce à l'opérateur d'affectation. En utilisant cet opérateur, vous essayez de dire que dict_b pointera vers le même objet que dict_a.
>>> dict_b["age"] = 26 >>> dict_b {'address': '221B Baker street', 'name': 'John', 'age': 26} >>> dict_a {'address': '221B Baker street', 'name': 'John', 'age': 26} >>>
Correct: utilisez les méthodes copy () ou deepcopy ().
>>> dict_c = dict_b.copy() >>> dict_c["location"] = "somewhere" >>> dict_c {'address': '221B Baker street', 'name': 'John', 'age': 26, 'location': 'somewhere'} >>> dict_b {'address': '221B Baker street', 'name': 'John', 'age': 26} >>> dict_a {'address': '221B Baker street', 'name': 'John', 'age': 26} >>>
Voyez la différence entre la copie et la copie profonde.2. Touches du dictionnaire
Essayons d'ajouter des valeurs au dictionnaire:
>>> dict_a = dict() >>> dict_a {} >>> dict_a[1] = "apple" >>> dict_a[True] = "mango" >>> dict_a[2] = "melon"
Si nous essayons d'afficher le dictionnaire à l'écran, que verrons-nous?
>>> dict_a {1: 'mango', 2: 'melon'}
Que s'est-il passé, où est la vraie clé?
Il faut se rappeler que la classe booléenne hérite de Integer (entiers). Et un entier équivalent à True est 1; le faux équivalent est 0. Par conséquent, la valeur de la clé 1 est simplement remplacée.
>>> isinstance(True, int) True >>> isinstance(False, int) True >>> True == 1 True >>> False == 0 True
3. Mise à jour des listes ou des dictionnaires
Supposons que vous souhaitiez ajouter un élément à une liste.
>>> list_a = [1,2,3,4,5] >>> list_a = list_a.append(6) >>> list_a >>>
Ou essayez de mettre à jour le dictionnaire.
>>> dict_a = {"a" : "b"} >>> dict_a = dict_a.update({"c" : "d"}) >>> dict_a >>>
Essayons maintenant d'organiser la liste.
>>> list_b = [2,5,3,1,7] >>> list_b = list_b.sort() >>> list_b >>>
Pourquoi rien ne sort, que faisons-nous de mal?
La plupart des méthodes de conteneur (telles que le tri, la mise à jour, l'ajout, l'ajout, etc.) sont optimisées à des fins de performances et évitent de créer inutilement des copies distinctes.
N'essayez pas d'attribuer la valeur de retour de ces méthodes à une variable.
Correctement: >>> list_a = [1,2,3,4,5] >>> list_a.append(6) >>> dict_a = {"a" : "b"} >>> dict_a.update({"c" : "d"}) >>> dict_a {'c': 'd', 'a': 'b'} >>> list_a.sort() >>> list_a [1, 2, 3, 4, 5, 6]
4. Chaînes internées
Dans certains cas, Python essaie de réutiliser des objets immuables existants. L'internement de chaînes en est un exemple.
>>> a = "gmail" >>> b = "gmail" >>> a is b True
Ici, nous avons essayé de créer deux objets différents - des chaînes. Mais lorsque nous les avons testés pour leur équivalence, il s'est avéré qu'ils coïncidaient complètement. C'est parce que Python n'a pas créé un autre objet b, mais a fait b indiquer la première valeur de "gmail".
Toutes les chaînes de longueur 1 sont internées. Les lignes qui ont autre chose que des caractères ASCII, des chiffres et des traits de soulignement ne seront pas internées.
Voyons ça.
>>> a = "@gmail" >>> b = "@gmail" >>> a is b False
Souvenez-vous également que == est différent de l'opérateur is. L'opérateur == vérifie si les valeurs sont équivalentes ou non, tandis que l'opérateur is vérifie si les deux variables font référence au même objet.
>>> a = "@gmail" >>> b = "@gmail" >>> a is b False >>> a == b True
Gardez donc cela à l'esprit lorsque vous utilisez des chaînes immuables ou les opérateurs == et is.
5. Les arguments par défaut sont évalués une fois.
Prenons un exemple:
def func(a, lst=[]): lst.append(a) return lst print(func(1)) print(func(2))
Selon vous, qu'est-ce qui sera affiché après deux impressions?
Exécutons le code.
>>> def func(a, lst=[]): ... lst.append(a) ... return lst ... >>> print(func(1)) [1] >>> print(func(2)) [1, 2]
Pourquoi la deuxième sortie de cas [1, 2]? Cela ne devrait-il pas être juste [2]?
Ainsi, le hic est que les arguments par défaut ne sont évalués qu'une seule fois. La première fois que la fonction a été appelée, func (1), la liste a été évaluée et s'est rendue compte qu'elle était vide. Cela signifie que vous pouvez ajouter 1. Mais lors du deuxième appel - func (2) - il y a déjà un élément dans la liste, donc [1, 2] est affiché.
Bonus: pas besoin de mélanger les espaces et les tabulations. Mais ne le fais pas.