返回顶部

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)

  

输出结果如下

 

posted @ 2018-12-10 01:05  Crazymagic  阅读(267)  评论(0编辑  收藏  举报