python中的 += 与 +

这一部分首先要理解python内存机制,Python中一切皆对象。

可变对象 list dict set
不可变对象 数值型(int float) 字符串类型 tuple

  对于+号操作,可变对象和不可变对象调用的都是__add__操作;对于+=号操作,可变对象调用__iadd__,不可变对象调用的是__add__(不可变对象没有__iadd__,__iadd__是原地修改)。可以理解为对于可变对象,+ 操作改变了值,id改变,而+=是本地操作,其值原地修改。

  对于不可变对象,改变了原来的值,其别名(变量名)绑定到了新值上面,id肯定会改变。如a=3,b=3,id(a)与id(b)是一样的,即a和b指向同一块内存区域;c=5,d=5,id(c)与id(d)是一样的,即c和d指向同一块内存区域;对于string来说也是这样的。当a=4的时候,此时a指向的就是另一块区域了。所以说对象是不可改变的。(另外Python有垃圾回收机制,当b=7的时候,此时保存3的内存区域不在被使用,那么就会被回收掉了)

  对于可变对象,+改变了原来的值,其别名(变量名)绑定到了新值上面,id肯定会改变。如l1=[1,2,3],l2=[1,2,3],id(l1)与id(l2)是不同的,虽然它们的内容一样,但是它们指向的是不同的内存地址,一个变化不会影响另外一个;如l3=[4,5,6],l4=l3,id(l3)与id(l4)是相同的,即l3和l4指向同一块内存区域,此时l3实际上是对列表对象的引用,l4=l3即引用的传递,两个引用指向了同一个地址,所以一个变化会影响到另外一个。

 

+=时原地修改,改变的是对象

 

+时l3指向了新的对象,id改变了,此时l3改变不会影响l4

 


  对于不可变对象,不会对调用函数中的数据造成影响;对于可变对象而言,如list和dict,因其为复合类型,所以会对调用函数中的数据造成影响。可以理解为python函数传参时传的时引用类型,也就是指针,不可变对象传的为一级指针。

  一个函数内部的任何类型的赋值都会把一个名称划分为本地的。这包括=语句,import中的模块名称、def中的函数名称、函数参数名称等。如果在def中以任意方式赋值一个名称,它都将对于该函数称为本地的。

 

报错:

注意:原处改变的对象并不会把变量划分文本地变量,实际上,只是对变量名赋值才可以。例如变量名L在模块的顶层被赋值为一个列表,在函数内部的像L.append(x)这样的语句并不会将L划分为本地变量,而L=Y却可以。修改一个对象并不是对一个名称赋值。

变量名解析:LEGB原则:
  在函数中使用未认证的变量名时,python搜索4个作用域:本地作用域(L),之后是上一层结构中的def或者lambda本地作用域(E),之后是全局作用域(G),最后是内置作用域(B)
  

 

posted @ 2019-05-29 10:32  呔!妖精。。。  阅读(403)  评论(0编辑  收藏  举报