06 python对象引用、可变性和垃圾回收
python中的变量是什么
python和java中的变量本质不一样,python的变量实质上是一个指针(固定大小)可以指向 int str等,类似于一个便利贴
java的变量类似与一个盒子声明盒子是什么类型,把值存放进去
a = 1 a = "abc"
1 先生成 int 对象1 后,a贴在 这个对象上 a的大小固定指向这个对象
2 先生成 str 对象'abc' 后,a贴在 这个对象上 a的大小固定指向这个对象
==和is的区别
==主要是判断两个对象的值是否相等
is是判断两个对象是否指向的是同一个地址
a=[1,2,3,4] b=[1,2,3,4] # 判断两个对象是否指向同一个地址 print(a is b) print(type(a) is list) # 判断两个对象的值是个相等 print(a == b)
del语句和垃圾回收
python中的垃圾回收采用的是引用计数机制
创建一个对象进行赋值的时候,引用计数+1,删除一个该对象的引用时引用计数-1,当这个对象的引用计数为0时,回收这个对象
#cpython中垃圾回收的算法是采用 引用计数 a = object() # obj 引用计数+1 b = a # obj 引用计数+1 del a # obj 引用计数-1
一个经典的参数错误
如果有一个默认参数是一个可变的类型如list,如果我们使用这个默认的参数不传值覆盖的话,多次使用该方法的时候就会出现共用的情况
class Company: def __init__(self, name, staffs=[]): self.name = name self.staffs = staffs def add(self, staff_name): self.staffs.append(staff_name) def remove(self, staff_name): self.staffs.remove(staff_name) if __name__ == "__main__": com1 = Company("com1", ["bobby1", "bobby2"]) # 把默认的列表覆盖 com1.add("bobby3") com1.remove("bobby1") print (com1.staffs) com2 = Company("com2") # 使用默认的列表 com2.add("bobby") print(com2.staffs) print (Company.__init__.__defaults__) # 查看一个对象的默认值 com3 = Company("com3") # 使用默认的列表和com2中的列表是同一个 com3.add("bobby5") # com2和com3共用一个staffs print (com2.staffs) print (com3.staffs) print (com2.staffs is com3.staffs)
输出结果如下