python重点知识,必须掌握
python语言层次方面
is 与 ==
new 和__init__
__new__
方法
class A(object):
def __init__(self):
print("这是 init 方法")
def __new__(cls):
print("这是 new 方法")
return object.__new__(cls)
A()
总结
-
__new__
至少要有一个参数cls,代表要实例化的类,此参数在实例化时由Python解释器自动提供
-
__new__
必须要有返回值,返回实例化出来的实例,这点在自己实现__new__
时要特别注意,可以return父类__new__
出来的实例,或者直接是object的__new__
出来的实例
-
__init__
有一个参数self,就是这个__new__
返回的实例,__init__
在__new__
的基础上可以完成一些其它初始化的动作,__init__
不需要返回值
- 我们可以将类比作制造商,
__new__
方法就是前期的原材料购买环节,__init__
方法就是在有原材料的基础上,加工,初始化商品环节。
深拷贝、浅拷贝
深拷贝:是对一个对象所有层次的拷贝(递归)
浅拷贝:是对一个对象的顶层拷贝(拷贝了引用,没有拷贝内容)
浅拷贝对不可变类型和可变类型的copy不同:可变类型则开辟新内存id,不可变类型则拷贝引用
生成器、迭代器、闭包、装饰器
生成器:中括号的比如(x for x in range(5)) 是生成器。
注意与列表生成式的区别。[x for x in range(5)]是列表生成式
协程:关键字yield。当协程执行到yield关键字时,会暂停在那一行,等到主线程调用send方法发送了数据,协程才会接到数据继续执行。
# 生成器yield、协程实现多任务
def test1():
while True:
print("---1---")
yield None # 遇到了yield就会停下来
def test2():
while True:
print("---2---")
yield None # 遇到了yield就会停下来
t1 = test1()
t2 = test2()
while True:
t1.__next__() # 使用__next__才会进行下一次,直到遇到yield停下
t2.__next__() # 使用__next__才会进行下一次,直到遇到yield停下
GC(垃圾回收)
- 以引用计数为主(缺点是无法解决循环引用的问题)
- 以隔代回收为辅
- Generation Zero
- 在创建对象之前,python先有一个链子(相当于双向链表),只要一创建对象,就把这个对象放到这个链子上去,也就是链子上能找到这个对象
- 新创建的对象一般在这条链子上
- 隔代回收最核心的方式:如果某些对象是循环引用,则在没有别的变量引用它们的前提下,它们的值为不为0,经过一定的检测,检查是否有循环引用,然后某些对象值减一(有引用指向的那些对象,减1之后不会是0),看看它们是不是0,如果是0,则直到它们一定是垃圾,然后把它们清掉
- 在同一条链子上,如果有两个对象互相引用,则计数肯定不是0,在一定的条件下,(先判断两个对象之间有没有相互引用)把某些对象的引用计数通通减一,然后把值为0的对象从链子上删除、内存中释放。把不是0的对象放到另一条链子去
- 经过隔代处理后,没有相互引用的对象放到下面两条链子Generation One/Two上
- 然后Generation Zero链子重新变空,等待新对象的加入
- Generation One
- 存放Generation Zero处理之后还存在的对象(都是没有相互引用的对象)
- 等待Generation Zero清零多次之后,才对Generation One清理一次
- Generation Two
- 存放Generation One进行多次处理之后还存在的对象
- 等待Generation One清零多次之后,才对Generation Two清理一次
(拓展一点:与Python很相似的一种语言Ruby,它的垃圾回收机制是标记-清除策略)
range 在python2与python3的区别
python2中,range是创建一个列表。而xrange则相当于与python3的range
python3中,range是创建一个生成器,每次调用next取一个元素。