# 第七章:对象引用、可变性和垃圾回收

# 7.1 python 的变量是什么

  • java 中变量相当于申请一个盒子,盒子有类型大小之说
  • python 中变量,类似一个指针,指针的值是固定的,类似便利贴,可以贴到任何对象上

    # a 贴到 1 上面
    a = 1
    # a 再贴到 'abc' 上
    a = 'abc'
    # 注意顺序: 先生成对象,然后贴便利贴

    la = [1, 2, 3]
    lb = la
    # is, 本质 id(a) 与 id(b) 比较
    print(lb is la)       # True, id 相同
    print(id(la), id(lb))

    la.append(100)
    print(lb)  # lb 和 la 指向相同对象,lb 会发生变化

# 7.2 is 和 == 区别

  • is 比较 id()
  • == 比较 变量值

    # is, 本质 id(a) 与 id(b) 比较
    # = 右边为对象时,表示生成新对象
    a = [1, 2, 3, 4]
    b = [1, 2, 3, 4]
    print(a is b)   # False, 说明 id 不同
    print(id(a), id(b))
    print(a == b)   # True, 值相同,内部 __eq__ 魔法函数

    # 内部优化 小整数、小字符串 全局唯一 intern机制
    a1 = 1
    a2 = 1
    print(a1 is a2)     # True

    s1 = 'abc'
    s2 = 'abc'
    print(s1 is s2)     # True


    class People:
        pass


    # People 全局唯一
    person = People()
    print(type(person) is People)   # True

# 7.3 del 语句和垃圾回收


    # python 中垃圾回收算法为 引用计数

    a = 1
    b = a
    del a
  • del 触发 del 逻辑
  • 对象引用计数为 0 时,会被垃圾回收

# 7.4 一个经典的参数错误

a, b 都是整型时


    def add(a, b):
        a += b
        return a

    if __name__ == '__main__':
        a, b = 1, 2
        c = add(a, b)
        print('a: %s, b: %s, c: %s' % (a, b, c))
        # 结果为 a: 1, b: 2, c: 3
        # a 未发生变化

a, b 都是列表时


    def add(a, b):
        a += b
        return a

    if __name__ == '__main__':
        a, b = [1, 2], [3, 4]
        c = add(a, b)
        print('a: %s, b: %s, c: %s' % (a, b, c))
        # 结果为 a: [1, 2, 3, 4], b: [3, 4], c: [1, 2, 3, 4]
        # a 发生变化

a, b 都是元组时


    def add(a, b):
        a += b
        return a


    if __name__ == '__main__':
        a, b = (1, 2), (3, 4)
        c = add(a, b)
        print('a: %s, b: %s, c: %s' % (a, b, c))
        # 结果为 a: (1, 2), b: (3, 4), c: (1, 2, 3, 4)
        # a 未发生变化

默认类型为可变类型时


    class Company:
        def __init__(self, name, staff_list=[]):
            self.name = name
            self.staff_list = staff_list

        def add(self, staff):
            self.staff_list.append(staff)

        def remove(self, staff):
            self.staff_list.remove(staff)


    if __name__ == '__main__':
        com1 = Company('com1', ['staff1', 'staff11'])
        com1.add('staff111')
        com1.remove('staff11')
        print(com1.staff_list)

        com2 = Company('com2')
        com2.add('staff2')

        com3 = Company('com3')
        com3.add('staff3')

        print(com2.staff_list)  # ['staff2', 'staff3']
        print(com3.staff_list)  # ['staff2', 'staff3']
  • 默认值为可变类型 [],com2.staff_list 和 com3.staff_list 指向一块内存空间

# 7.5 本章小结

  • python 变量的本质
  • is、== 和 = 区别与联系
  • del 和垃圾回收
上次更新: 8/26/2022, 2:06:10 PM