• 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没有实现减法和除法的操作。但乘法确实也是这样。

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

  • 相关阅读:
    springmvc中request的线程安全问题
    日志帮助类
    模态框的实现
    getopts的使用方法
    自动生成头文件的脚本
    shell脚本中出现图形化界面
    Linux Centos关机命令
    Linux下IP的存储位置
    tar只解压tar包中某个文件
    Swift 笔记1
  • 原文地址:https://www.cnblogs.com/hujingnb/p/12037636.html
Copyright © 2020-2023  润新知