a = [1,2,3,4]
b = a
每个变量都有标识,类型和值.对象一旦创建,它的标识绝不会变;标识可以简单的理解为对象在内存中的地址.
- 别名
a
跟b
是别名指向[1,2,3,4]
,如果a增加新的内容,b也会增加. - 相等性
b == a
为true
.==
运算符比较连个对象的值(对象中保存的数据) - 标识
b is a
为true
,因为他们都指向[1,2,3,4]
这个列表,is
比较对象的标识
元组相对不可变性
- 元组保存对象的引用,跟
python
的集合set
一样,如果引用的元素是可变的,即便元组本身不可变,元素依然可变.即:元组的不可变形其实指tuple
数据结构的物理内容(即保存的引用)不可变,与引用对象无关
默认做浅层复制
-
浅层复制
: 1.复制了最外层容器,副本中的元素是源容器中元素的引用 2.他们的值相等,单两者指向不同的对象. 3.副本共享内部对象的引用 浅层复制
- 若所有元素都是不可变的,不存在任何问题,并节省了内存.
- 如果存在可变的元素,如
list
会导致意想不到的问题.
l1 = [3,[66,55,44],(7,8,9)]
l2 = list(l1)
l1.append(100) # 由于只复制了外层容器,这里仅有l1内容发生变化
l1[1].remove(55) # l1[1] 是一个list可变的元素,所有以l2[1]的元素也发生变化
l2[1] +=[33,22]
l2[2] += (10,11) # l2[2]是tuple,不可变的元素所有只有l2[2]发生变化.
深层复制,副本不共享内部对象的引用
函数的参数作为引用时
-
python
中唯一支持的参数传递模式是共享传参 call by sharing
-
共享传参:
函数的各个形式参数获得实参中各个运用的副本,即是函数内部的形参是实参的别名 -
影响:
函数可能会修改作为参数传入的可变对象,但无法修改那些对象的标识
不要使用可变类型作为参数的默认值可变参数
作为默认值会导致:如果么有指定内容,会共用一个对象
.所以通常使用Nono
作为接收可变值得参数的默认值
.
防御可变参数
- 如果定义函数的接受可变参数,应该谨慎的考虑调用方是否期望修改传入的参数.
del
和垃圾回收
- 对象绝不会自行销毁;然而,无法得到对象时,可能会被当做垃圾处理.
一个对象的引用数量为0的话会被销毁