Cet article présente principalement des informations pertinentes indiquant si les expressions i = x et i = i Jetons un coup d'œil ensemble ci-dessous.
Préface
J'ai récemment vu une question qui semblait très simple, mais en fait elle a une signification profonde. La question était les expressions Python i = x et i = i x Is. c'est équivalent ? 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 même, mais la valeur de l1 est différente, indiquant que i = x et i = i x ne sont pas équivalents, alors dans quelles circonstances sont-ils équivalents et dans quelles circonstances ne le sont-ils pas ?
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 : est utilisé pour identifier le caractère unique d'un objet en mémoire. Il ne changera pas après la création de l'objet. La fonction id() peut afficher. l'objet. L'identifiant unique du type
: détermine les opérations prises en charge par l'objet. Différents types d'objets prennent en charge différentes opérations. attribut length, contrairement aux 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, le value est toujours la valeur lors de sa première création. Toute opération sur l'objet entraînera la création d'un nouvel objet.
>>> a = 1 >>> id(a) 32574568 >>> a += 1 >>> id(a) 32574544
L'entier "1" est un objet immuable Lorsqu'il est initialement attribué, a pointe vers l'objet entier 1, mais = est exécuté sur la variable. a. Après l'opération, 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.
Objet mutable (mutable)
La valeur d'un objet mutable peut être modifiée dynamiquement grâce à certaines opérations. Par exemple, un objet de liste peut ajouter continuellement des éléments à la liste via la méthode append, 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 mémoire. Adresse, lorsque vous opérez sur l’une des variables, cela affectera également l’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
Après avoir effectué l'opération d'ajout, l'adresse mémoire de l'objet ne changera pas, x et y toujours pointer vers Il s’avère qu’il s’agit du même objet, mais sa valeur a changé.
Après avoir compris les objets mutables et les objets immuables, revenons à la question elle-même, quelle est la différence entre = et ?
= L'opération tentera d'abord d'appeler la méthode __iadd__ de l'objet, si une telle méthode n'existe pas, alors essayez d'appeler la méthode __add__ . Jetez d'abord un coup d'œil à ces deux méthodes. Quelle est la différence entre les deux méthodes
La différence entre __add__ et __iadd__
La méthode __add__ reçoit deux paramètres et renvoie leur somme, deux Les valeurs des paramètres ne sont pas modifiées. 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 variable. il n'existe pas de méthode __iadd__ pour les objets immuables.
>>> hasattr(int, '__iadd__') False >>> hasattr(list, '__iadd__') True
Évidemment, les objets entiers n'ont pas __iadd__, tandis que les objets liste fournissent la méthode __iadd__.
>>> l2 += [3] # 代码1:使用__iadd__,l2的值原地修改
代码1中的 += 操作调用的是__iadd__方法,他会原地修改l2指向的那个对象本身的值
>>> l2 = l2 + [3] # 代码2:调用 __add__,创建了一个新的列表,赋值给了l2
而代码2中的 + 操作调用的是 __add__ 方法,该方法会返回一个新的对象,原来的对象保持不变,l1还是指向原来的对象,而l2已经指向一个新的对象。
以上就是表达式 i += x 与 i = i + x 的区别。因此对于列表进行 += 操作时,会存在潜在的bug,因为l1会因为l2的变化而发生改变,就像函数的参数不宜使用可变对象作为关键字参数一样。
更多详解Python中表达式i += x与i = i + x是否等价相关文章请关注PHP中文网!