变量
- python变量不是盒子,是标注。
- 创建在前,分配在后。是把变量分配给对象,而不是把对象分配给变量。
- 一个对象可以分配多个标签,而一个标签只能贴到一个对象上。
is
与==
==
运算符比较两个对象的值,调用对象的__eq__
方法。如果是自定义类型,并且没有重载__eq__
方法,则==
会比较两个对象的id
–标识。is
比较对象的id
。- 在变量和单例值之间比较时应该使用
is
,特别是检查变量绑定的值是不是None
时。因为is
方法不能被重载,速度更快。不用像==
那样去寻找有没有重载__eq__
方法。
元组的相对不可变性
tuple
虽然被划分为不可变序列,但是相对于str
而言,tuple
的不可变性又有自己的特点。对于不可变序列在tuple
直接保存,而对于可变序列则保存引用。
1 | import sys //改变元组内可变序列的值,而元组的内存占用并没有改变。 |
由此我们可以得出,其实元组真的是不可变的。元组内只是保存了可变序列的引用,而我们修改的也是可变序列的值,并没有修改它的标识。所以某种程度上元组的值并没有改变……….
深拷贝与浅拷贝
这是一个好网站,网站的动画演示非常到位,可以把下面的代码输进去试一下。
1 | l1 = [3, [66, 55, 44], (7, 8, 9)] |
__deepcopy__
deepcopy()
会调用__deepcopy__
方法来进行深拷贝。深拷贝时对于可变与不可变序列都会创建新的对象,而不是增加引用。deepcopy
函数会记住已经复制的对象,因此能优雅的处理循环引用。
函数的参数
函数的参数不能是可变序列
函数的参数不能是可变序列
函数的参数不能是可变序列
函数的参数不能是可变序列
重要的事情说三遍!!!
1 | class HauntedBus: |
在HauntedBus
中,passagers
的默认值是一个空列表,也可以说它引用了一个空列表。当我们对这个空列表做增删操作时,使得其中的值发生改变。但是注意的是之后所有的HauntedBus
实例中,passagers
都是引用了同一个列表,因此之后创建的所有实例,其passagers
属性都不为空。
防御可变参数
当传入的参数是可变序列是,并且我们要修改它的内容,但是不希望对原值产生影响。这时我们便需要注意一些事项,可以选择用工厂函数产生这个参数的副本,对其副本进行操作,便可以避免对原参数产生影响。这里可以类比C语言中的值传递和指针传递(也可以是名字传递)。
1 | class HauntedBus: |
垃圾回收
对象绝不会自行销毁;然而,无法得到对象时,可能会被当作垃圾回收。
del
del
命令可能会导致对象被当作垃圾回收,但是更多的时候仅仅是删除对象的一个引用。- Cpython2.0增加的分代垃圾回收算法,可以检测引用循环中涉及的对象组,如果一组对象之间相互引用,导致无法获取,则被回收。
- 一般情况下我们不需要显示地调用
del
函数,python会帮我们做好内存回收工作。
弱引用
引用对象,但不增加对象的引用计数。
1 | import weakref |