第八章 - 对象引用、可变性和垃圾回收

对象引用、可变性和垃圾回收

本章先以一个比喻说明 Python的变量: 变量是标签,而不是盒子。

8.1 变量不是盒子

可变对象赋值 就是引用同一个对象, 不可变对象赋值则是复制一个副本。

Python说明标识不通的方式: a is not b

在Cpython中, id() 返回对象的内存地址。

8.2 在 == 和 is 之间选择

"=="运算符比较两个对象的“值”,而is比较对象的引用。

is运算符比 == 速度快, 是因为它不能重载(详见重载运算符),所以Python不用寻找并调用特殊方法,而是直接比较两个整数ID,而 a == b 是语法糖, 等同于a.__eq__(b)。

在变量和单例值之间比较时,应该使用is, 最常使用is检查变量绑定的值是不是None。

x is None.   x is not None

a = [1,2,3]
b = [1,2,3]
c = a

print(a is b)
>>>
False

print(c is a)
>>>
True

比较字符串或整数是否相等时,应该使用 == , 而不是is。

8.3 默认做浅复制

也就是说容器内的可变对象还只是一个引用。

浅复制共享内部对象引用, 深复制不共享内部对象引用。

class Bus(object):
    def __init__(self, passengers=None):
        if passengers is None:
            self.passengers = []    # 注意这里接收的是一个可变对象
        else:
            self.passengers = list(passengers)  # 注意这里不是简单的引用,而是使用list创建了一个副本
    
    def pick(self, name):
        self.passengers.append(name)
    
    def drop(self, name):
        self.passengers.remove(name)

注意: 不要使用可变类型作为参数的默认值, 因此通常使用None作为接收可变对象的参数的默认值。

 

8.5 del和垃圾回收

del语句删除名次,而不是对象。 del不删除对象,而是删除对象引用。

在Cpython中,垃圾回收使用的主要算法是引用计数;实际上每个对象都会统计有多少引用指向自己,当引用计数归零时,对象立即就被销毁。

弱引用不会增加对象的引用数量, 弱应用不会妨碍所指对象被当作垃圾回收。

弱引用在缓存应用中很有用,因为我们不想仅因为被缓存引用着而始终保存缓存对象。

内置函数weaker.ref提供弱引用

 

 

posted @ 2017-07-25 22:53  Vincen_shen  阅读(131)  评论(0)    收藏  举报