Les expressions Python i = x et i = i x sont-elles équivalentes ? Si votre réponse est oui, alors félicitations, vous avez raison à 50 %. Pourquoi dites-vous que ce n’est qu’à moitié vrai ? Selon notre compréhension générale, ils sont équivalents. Il n’y a pas de similitudes ou de différences entre les deux lorsqu’il s’agit d’opérations sur des nombres entiers, mais en est-il de même pour les opérations sur les listes ? Regardez d'abord les deux morceaux de code suivants :
Code 1
>>> l1 = range(3) >>> l2 = l1 >>> l2 += [3] >>> l1 [0, 1, 2, 3] >>> l2 [0, 1, 2, 3]
Code 2
>>> l1 = range(3) >>> l2 = l1 >>> l2 = l2 + [3] >>> l1 [0, 1, 2] >>> l2 [0, 1, 2, 3]
La valeur de l2 dans le code 1 et le code 2 est la pareil, mais les valeurs de l1 sont différentes, ce qui signifie que i = x et i = i x ne sont pas équivalents. Alors dans quelles circonstances sont-ils équivalents et dans quelles circonstances ne sont-ils pas équivalents ?
Avant de clarifier cette question, vous devez d'abord comprendre deux concepts : les objets mutables et les objets immuables.
Il existe trois attributs communs à tout objet en Python : l'identifiant unique, le type et la valeur.
Identification unique : utilisée pour identifier le caractère unique d'un objet en mémoire. Elle ne changera pas après la création de l'objet. La fonction id() peut visualiser l'identification unique de l'objet. Type : Déterminé Les opérations prises en charge par l'objet sont différentes. Différents types d'objets prennent en charge différentes opérations. Par exemple, les listes peuvent avoir un attribut de longueur, mais pas les entiers. De même, une fois le type d'un objet déterminé, il ne changera pas. La fonction type() peut renvoyer les informations de type de l'objet.
La valeur d'un objet est différente d'un identifiant unique. Toutes les valeurs d'objet ne sont pas immuables. Les valeurs de certains objets peuvent être modifiées via certaines opérations. Les objets dont les valeurs peuvent changer sont appelés. objets mutables. (mutable), les objets dont les valeurs ne peuvent pas être modifiées sont appelés objets immuables (immuables)
Objets immuables (immuables)
Pour les objets immuables, la valeur est toujours la valeur lorsque il a été créé en premier, toute opération sur cet objet entraînera la création d'un nouvel objet.
L'entier "1" est un objet immuable. Lorsqu'il est initialement attribué, a pointe vers l'objet entier 1, mais après avoir effectué l'opération = sur la variable a, a pointe vers un autre objet entier 2, mais l'objet 1 est toujours là sans aucun changement, et la variable a pointe déjà vers un nouvel objet 2. Les objets immuables courants incluent : int, tuple, set, str.>>> a = 1 >>> id(a) 32574568 >>> a += 1 >>> id(a) 32574544
Objet mutable (mutable)
La valeur d'un objet mutable peut être modifiée dynamiquement par certaines opérations, comme un objet liste, qui peut être continuellement modifié via la méthode append Ajoutez des éléments à la liste en continu et la valeur de la liste change constamment Lorsqu'un objet variable est affecté à deux variables, elles partagent le même objet d'instance et pointent vers la même adresse mémoire lorsqu'elles fonctionnent sur n'importe laquelle. des variables, et cela affectera également une autre variable.
>>> x = range(3) >>> y = x >>> id(x) 139726103041232 >>> id(y) 139726103041232 >>> x.append(3) >>> x [0, 1, 2, 3] >>> y [0, 1, 2, 3] >>> id(x) 139726103041232 >>> id(y) 139726103041232
= L'opération tentera d'abord d'appeler la méthode __iadd__ de l'objet. S'il n'existe pas de telle méthode, essayez d'appeler la méthode __add__. Jetez d'abord un coup d'œil à ces deux. Quelle est la différence entre les méthodes
La différence entre __add__ et __iadd__
La méthode __add__ reçoit deux paramètres et renvoie leur somme. pas changer.
La méthode __iadd__ reçoit également deux paramètres, mais c'est une opération sur place, ce qui signifie qu'elle changera la valeur du premier paramètre, car cela nécessite que l'objet soit mutable, donc il n'y a pas besoin d'immuable objets méthode __iadd__.
Évidemment, les objets entiers n'ont pas __iadd__, tandis que les objets liste fournissent la méthode __iadd__.>>> hasattr(int, '__iadd__') False >>> hasattr(list, '__iadd__') True
>>> l2 += [3] # 代码1:使用__iadd__,l2的值原地修改
>>> l2 = l2 + [3] # 代码2:调用 __add__,创建了一个新的列表,赋值给了l2
Ce qui précède est la différence entre les expressions i = x et i = i x. Par conséquent, il y aura des bugs potentiels lors de l'exécution d'opérations = sur des listes, car l1 changera en raison des changements dans l2, tout comme les paramètres d'une fonction ne doivent pas utiliser d'objets variables comme paramètres de mots-clés.