1 变量与对象
- 对象:内存中存储数据的实体,有明确的类型。在Python中,一切都是对象,函数也是对象。
- 变量:指向对象的指针,对对象的引用。作为弱类型语言,Python中变量是没有类型的。
2 不可变对象与可变对象
- 不可变对象:对象对应内存中的值不会变,因此如果指向该对象的变量被改变了,会重新开辟一片内存,变量指向这个新的内存,包括int、float、str、tuple。
- 可变对象:对象对应内存中的值可以改变,因此变量改变后,该对象也会改变,即原地修改,如list、dict、set等。
对于不可变对象,所有指向该对象的变量在内存中共用一个地址:
a = 1
b = 1
c = a + 0
# 使用id函数查看三个变量的内存地址
flag = id(a) == id(b) and id(a) == id(c)
print(id(a)) # 1986179296
print(id(b)) # 1986179296
print(id(c)) # 1986179296
print(flag) # True
3 直接赋值
在Python中对象赋值实际上是对象的引用。当创建一个对象,然后把它赋给另一个变量的时候,并没有拷贝这个对象,而只是拷贝了这个对象的引用。
直接赋值默认浅拷贝,只传递对象的引用,原始列表改变,被赋值的b也会做相同的改变
# 直接赋值
# a和b引用相同的list,所以会相互改变
alist = [1, 2, 3, ['a','b']]
b = alist
alist.append(5)
alist[3].append('c')
print("List a:", alist)
print("List b:", b)
4 浅拷贝
浅拷贝没有拷贝子对象,原始数据改变时,子对象会改变。
# 浅拷贝
import copy
alist = [1, 2, 3, ['a', 'b']]
# 没有拷贝子对象,公用一个可变list对象
c = copy.copy(alist)
# 非可变子对象,所以不会改变c
alist.append(5)
# 可变子对象,会改变c
alist[3].append('ccc')
print("List a:", alist)
print("List c:", c)
5 深拷贝
深拷贝包含对象里面的对象,所以原始对象的改变不会造成深拷贝对象的改变。
# 深拷贝
import copy
alist = [1, 2, 3, ['a', 'b']]
# alist和d完全独立所有对象
d = copy.deepcopy(alist)
alist.append(5)
alist[3].append('ccc')
print("List a:", alist)
print("List d:", d)