python小白 问关于a+=a 和a=a+a的区别

第一段代码:

# -*- coding:gb2312 -*-

a = [100]

def test(num):
    num += num #第一段代码
    print(num)
    
test(a)
print(a)

执行结果:

clipboard.png

第二段代码:

# -*- coding:gb2312 -*-

a = [100]

def test(num):
    num = num + num  #这个地方改了一下
    print(num)
    
test(a)
print(a)

执行结果:

clipboard.png

我的问题:
num += num不应该直接等价于mun = num+num 么
为什么算出来结果却是不一样的?这个是什么情况

阅读 6.1k
评论
    4 个回答

    在python中,a=a+b是先创建一个新的对象并让变量a引用这个对象,a+=b是让a所引用的对象的变成a+b的值

      你可以尝试进行这样的操作,

      In [1]: a = [100]
      
      In [2]: b = [100]
      
      In [3]: id(a)
      Out[3]: 79308552L
      
      In [4]: id(b)
      Out[4]: 79342728L
      
      In [5]: a += a
      
      In [6]: b = b + b
      
      In [7]: id(a)
      Out[7]: 79308552L
      
      In [8]: id(b)
      Out[8]: 79341192L

      通过id()这个函数可以得到变量所分配的内存地址。通过实验发现使用了+的变量地址发生了变化,也就是你所说的num+=num与num=num+num不等价
      但是,当做如下骚操作时候又会发现啪啪啪打脸

      In [19]: a = (0,)
      
      In [20]: b = (0,)
      
      In [21]: id(a)
      Out[21]: 82230688L
      
      In [22]: id(b)
      Out[22]: 82208920L
      
      In [23]: a += a
      
      In [24]: b = b + b
      
      In [25]: id(a)
      Out[25]: 79268296L
      
      In [26]: id(b)
      Out[26]: 79328392L

      分配的地址似乎一直在改变。
      原因在于,Python中的数据结构分为可变(mutable)和不可变(immutable)。
      对于可变类型,=和+=有着明显的不同,如上面的list:
      +表示连接操作,+=表示追加
      对于不可变类型,=和+=就是一样的操作,如上面的tuple
      可变类型与不可变类型的本质在于内存空间是否可变~

        • 156

        首先看出区别在于

        In [26]: def test(num):
            ...:     num = num + num
            ...:     print (num)
            ...:
        
        In [27]: def test1(num):
            ...:     num += num
            ...:     print (num)
            ...:
        
        In [28]: import dis
        
        In [29]: dis.dis(test)
          2           0 LOAD_FAST                0 (num)
                      3 LOAD_FAST                0 (num)
                      6 BINARY_ADD  #区别在这儿
                      7 STORE_FAST               0 (num)
        
          3          10 LOAD_FAST                0 (num)
                     13 PRINT_ITEM
                     14 PRINT_NEWLINE
                     15 LOAD_CONST               0 (None)
                     18 RETURN_VALUE
        
        In [30]: dis.dis(test1)
          2           0 LOAD_FAST                0 (num)
                      3 LOAD_FAST                0 (num)
                      6 INPLACE_ADD  #看这儿
                      7 STORE_FAST               0 (num)
        
          3          10 LOAD_FAST                0 (num)
                     13 PRINT_ITEM
                     14 PRINT_NEWLINE
                     15 LOAD_CONST               0 (None)
                     18 RETURN_VALUE
        

        可以看出分别调用的方法不同,分别是__add__,__iadd__
        加法运算符会计算出新的object来赋值给num
        增量赋值运算符修改原来的引用

        参考这儿: https://stackoverflow.com/que...

          Remember that arguments are passed by assignment in Python.

          傳參數在python是用assignment 不是reference,所以你傳a過去函數時傳的是a的值,而不是a本身。若你要改動a本身就需要用return傳值回來

          a = [100]
          
          def test(num):
              num = num + num  #这个地方改了一下
              return(num)      #这个地方再改了一下
              
          print(test(a))       #傳值回來
          print(a)
          a = test(a)
          print(a)
          

          結果:

          [100, 100]
          [100]
          [100, 100]
          
            撰写回答

            登录后参与交流、获取后续更新提醒

            相似问题
            推荐文章