python有两种对象:
- 不可变对象,如:int、float、str、tuple
- 可变对象,如:list、dict、set
目录
可变对象与不可变对象的含义
不可变对象
意义:改变内容(值)即为创建新对象
案例说明:
创建3个对象,前两个对象值相等。改变第二个对象,捕捉改变前后的对象ID。
int1 = 1
int2 = 1
int3 = 2
# 改变前
print(id(int1),id(int2),id(int3))
# 改变
int2 = int2+2
# 改变后
print(id(int1),id(int2),id(int3))
1906142224 1906142224 1906142256
1906142224 1906142288 1906142256
改变后,第二个对象ID发生改变。
小结
经过测试,发现int、float、str、tuple对象皆有此特性。改变值即为创建新对象。
不可变对象频发改变会消耗大量内存空间
可变对象
意义:改变(内容)值,并不会创建新对象,只在原有对象上进行修改。
案例说明:
创建3个对象,前两个对象值相等。改变第二个对象,捕捉改变前后的对象ID。
list1 = [1, 2, 3]
list2 = [1, 2, 3]
list3 = [1, 2, 3, 4]
# 改变前
print(id(list1),id(list2),id(list3))
# 改变
list2.append(4)
# 改变后
print(list2)
print(id(list1),id(list2),id(list3))
2491497852872 2491498301704 2491497756744
[1, 2, 3, 4]
2491497852872 2491498301704 2491497756744
改变后,第二个对象ID未发生改变。
小结
经过测试,发现list、dict、set对象皆有此特性。改变值即为在原对象上进行改变。
可变对象频发改变不会消耗大量内存空间,因为不会创建新对象。
总结
可变对象与不可变对象最重要的区别就是改变对象内容(值)后,是否创建新对象。
不可变对象:改变内容(值)即为创建新对象。
可变对象:改变(内容)值,并不会创建新对象,只在原有对象上进行修改。
函数的参数传递
核心问题:函数参数传递传的是引用还是内容(值)?
不可变对象作为函数参数
不可变类型传递的是内容(值)
案例:
预先创建一个不可变对象,设计一个3次循环的循环体,对实验过程进行重复3次,大样本观察。
函数内容为对传入的参数进行运算,运算前记录其对象ID。
a = 1
for i in range(3):
def aa(test):
print(id(test))
test+1
return 0
print(a)
print(id(a))
b=aa(a)
print(id(a))
print(a)
1
1906142224
1906142224
1906142224
1
1
1906142224
1906142224
1906142224
1
1
1906142224
1906142224
1906142224
参数内容(值)未发生改变,每次运行创建一个新对象(当对象值不重复时)。
小结
不可变对象作为函数参数,传递的是内容(值)。
可变对象作为函数参数
可变类型传递的是对象的引用
案例:
预先创建一个可变对象,设计一个3次循环的循环体,对实验过程进行重复3次,大样本观察。
函数内容为对传入的参数进行运算,运算前记录其对象ID。
a = [1,2,3]
for i in range(3):
def aa(test):
return test.append(4)
# 改变前
print(a)
print(id(a))
# 改变
b = aa(a)
# 改变后
print(a)
print(id(a))
print("----------------")
[1, 2, 3] 2491498533000 [1, 2, 3, 4] 2491498533000 ---------------- [1, 2, 3, 4] 2491498533000 [1, 2, 3, 4, 4] 2491498533000 ---------------- [1, 2, 3, 4, 4] 2491498533000 [1, 2, 3, 4, 4, 4] 2491498533000 ----------------
对象内容(值)发生改变,未创建新对象。
小结
可变对象作为函数参数,传递的是对象的引用,改变对象引用并不会创建新对象。
总结
可变对象和不可变对象作为函数参数传递最大区别为,参数传递的是引用还是内容。
不可变类型传递的是内容(值),可变类型传递的是对象的引用。