Python中的+=

引出

今天在运行之前写的一个Python脚本时,发生了一个奇怪的现象(我怎么老遇到奇怪的现象~~)。当时的代码大概长这样:

a = [1, 2, 3]
b = [4, 5, 6]
# ...一大段逻辑
c = a
c += b
# ...一大段逻辑
# 在这里,a变成了[1, 2, 3, 4, 5, 6]

首先,上面的代码一个函数过于长了,实在不像话

当时的情景是这样的,程序并没有想我预期中一样运行。我找了半天,没有找到对a变量的修改或赋值操作。

最终,发现了藏在中间的c变量,因为是列表对象的引用赋值,所以直接修改了a变量。我将两个变量的地址打印出来,确实是这样的。

本来,查到这里基本上破案了。也应该没有后续了

但我上网查了一下,有人说用 =+就不会出现这种情况,我轻蔑的笑了,有什么区别么?不信邪的我试了一下。

What?谁能告诉我发生了什么?

探究

根据我的推测,必然是+=操作改变的是原对象,=+操作返回了新的对象。尝试一下:

果不其然。在此破案。

解惑

都知道Python的运算符重载操作,加法调用的是__add__方法,+=调用的是__iadd__方法。既然产生这个现象,那一定是list对两个方法的实现不同咯。

尝试自己动手测试,写一个Test类,实现两个重载方法:

分别调用+==+

可以看到,都是新的值。如果修改一下方法的实现:

再测试就会发下,两个运算返回的都是同一个对象。水落石出,Python对两个不同的运算符使用了不同的实现方法。

一探究竟

那为什么Python会在 +=操作时,直接修改原对象。而=+操作却要返回新的对象呢?

简单推测一下,可能Python的作者认为,+=操作是要将后边的值加到自身上。而+则是两个值的运算操作。根据表达是也可以看出:

a += b # 这里只涉及两个变量,将b的内容直接加到a上
c = a + b # 这里涉及到了三个变量,将后两者内容相加后赋值给新的变量

最后,既然+==+的实现不同,那么同理列表的-==-*==*/==/的实现也必然不同。

哦,不好意思,list没有实现减法和除法的操作。但乘法确实也是这样。

好吧,之后再进行对象运算符重载时可以参考一下上面的做法,仔细想想还是很合乎逻辑的。

本文分享自微信公众号 - 烟草的香味(hujing-bc),作者:胡靖哥哥

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-12-13

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 6大设计原则之依赖倒置原则

    High level modules should not depend upon low level modules. Both should depend ...

    烟草的香味
  • MD文件图片base64自动编码

    不知道你在使用markdown写文章的时候有没有遇到过这样的烦恼, 文件写完了, 想将写完的文章粘贴到博客的时候, 你满心欢喜的复制粘贴, 但是发现图片根本复...

    烟草的香味
  • PHP 数组函数整理

    array_change_key_case($arr, $case=CASE_LOWER): 将数组键名修改为全大写或全小写, 返回是否成功

    烟草的香味
  • 【编程经验】基本运算符

    关注我们 今天就不给大家分享源码了,得照顾照顾咱们的初学者,给大家讲一讲基础的东西,比如说基本运算符 ,希望能对大家有所帮助。 C...

    编程范 源代码公司
  • 6. 简单又复杂的“运算符”,建议你看一哈

    昨天的《5. 很“迷”的字符与字符串》初稿本来很短的,但是我觉得内容太少了,就加了一些,结果好像就变得特别多〒▽〒。

    谭庆波
  • 快速学习ES6新特性-扩展运算符

    扩展运算符(spread)是三个点(…), 将一个数组转为用逗号分隔的参数序列 。

    cwl_java
  • 《挑战30天C++入门极限》C++运算符重载函数基础及其值返回状态

      除此之外,c++也规定了一些运算符不能够自定义重载,例如.、::、.*、.->、?:。   下面我们来学习如何重载运算符,运算符重载函数的形式是: ...

    landv
  • Java的运算符

    Java的运算符 运算符是一种特殊符号,用以表示数据的运算、赋值和比较等共分以下几种: 1.1括号:() [] 1.2一元运算符(只有1个操作数):!(逻...

    Java学习
  • 游戏服务端究竟解决了什么问题?

    当讨论到游戏服务端的时候,我们首先想到的会是什么?要回答这个问题,我们需要从游戏服务端的需求起源说起。

    李海彬
  • 10 行 Python 代码,批量压缩图片 500 张,简直太强大了

    原文地址:https://mp.weixin.qq.com/s/5hpFDgjCpfb0O1Jg-ycACw

    Python猫

扫码关注云+社区

领取腾讯云代金券