1.Python的内存管理机制:
Python中一切皆对象,每一个Python对象的核心都是一个结构体,它的内部有一个计数器,程序在运行时更新计数器,当引用计数为0时,它的内存是被是系统回收。
但是引用计数有个缺陷:不能解决容器对象循环引用的问题,容器对象保留了被引用对象的引用,非容器对象不可能出现循环引用问题;
循环引用的解决办法:
标记清除和分代回收
标记清除清除算法是基于GC(追踪回收技术)实现的垃圾回收算法,它分为两个阶段:第一个阶段是标记,GC会把所有的『活动对象』打上标记,第二阶段是把那些没有标记的对象『非活动对象』进行回收;
对象之间通过引用(指针)连在一起,构成一个有向图,对象构成这个有向图的节点,而引用关系构成这个有向图的边。从根对象(root object)出发,沿着有向边遍历对象,可达的(reachable)对象标记为活动对象,不可达的对象就是要被清除的非活动对象。根对象就是全局变量、调用栈、寄存器。
找到非活动对象后,Python使用一个双向链表将这些容器组织起来;不过,这种简单粗暴的标记清除算法也有明显的缺点:清除非活动的对象前它必须顺序扫描整个堆内存,哪怕只剩下小部分活动对象也要扫描所有对象。
分代回收:如果一个对象被检测了10次还没有被销毁,就减少对其的检测频率;基于这个假设,提出一套机制,即分代回收机制。
image.png
内存池管理:
当大量创建消耗小内存的对象时,c中频繁调用new/malloc会导致大量的内存碎片,致使效率降低;
内存池的概念就是内存会预先申请出一定数量的,大小相等的内存块备用,当有新的内存需求时,就先从内存池中分配内存这个需求,如果是大的对象,则直接调用 new/malloc 来申请新的内存空间。
2.python2与Python3的区别
python3多了很多优化机制,比如在python3中range(0,99)就不会完全加载到内存中
3.python中字符串使用join, 列表使join拼接成字符串条件是:list元素必须是str类型
3.深浅拷贝区别:
不可变对象:无被拷贝之说,id不变,值也不变,只是新创建一个对象替换旧的而已;
可变对象:无论深浅拷贝,其地址和值都不一样,确切的说,浅拷贝只重新开辟一块空间来copy第一层数据。
4.元组
元组中的一级元素不可被修改
5.函数
返回值数=0,返回None
返回值数=1,返回object
返回值数>1, 返回tuple
形参,实参
形参只有在被调用时,才会给分配内存空间,在调用结束释放内存空间;
位置参数和关键字(标准调用:实参和形参位置一一对应;关键字调用:位置无需固定)
默认参数
image.png
可变长参数:args和kwargs
image.png
函数全局变量与局部变量:
https://blog.csdn.net/dongtingzhizi/article/details/8973569
image.png
函数内部的变量名如果第一次出现,且出现在=前面,即被视为定义一个局部变量。
函数内部的变量名如果第一次出现,且出现在=后面,且该变量在全局域中已定义,则这里将引用全局变量,如果该变量在全局域中没有定义,当然会出现“变量未定义”的错误。
只要是使用*变量,而该变量在全局域中有定义,而在局部没有定义,则会使用全局变量;
在函数中,如果想给全局变量赋值,则需要用关键字global声明;
python3 nonlocal
image.png
python函数风湿理论
image.png
6.python内置函数
reduce(),map(),filter(),all(),any(),abs(),sorted(),super()
image.png
image.png
image.png
image.png
7.匿名函数
func=lambda x:x+1
print func(2)
8.sorted排序
image.png
9.函数式编程
高阶满足两个条件:
1.函数的传入参数为一个函数名
2.函数的返回值是一个函数名
10.迭代器生成器
image.png
生成器函数 yield
生成器表达式(i for i in range(5))
列表推导式 [i for i in [1,2,34]]
11.装饰器
本质就是函数,功能是为其他函数添加附加功能
原则:
1.不修改被修饰函数的源代码
2.不修改被修饰函数的调用方式
装饰器函数=高阶函数+函数嵌套+闭包
带参数->三层,第一层传参数,第二层传func,第三层传函数参数
12.常用Python模块
sys,os,time,json(json_dumps,json_loads,re正则匹配
13.类方法,静态方法,super,类装饰器
@property 它可以把被装饰的方法变成属性来赋值,方便实例化对象调用
将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则
@staticmethod 不需要表示自身对象的self和自身类的cls参数,就和使用普通的函数一样。
@classmethod 不需要self参数,但是第一个cls参数需要表示自身类的cls参数。
image.png
14.Python实现单例模式
image.png
new() 方法的特性:
new() 方法是在类准备将自身实例化时调用。
new() 方法始终都是类的静态方法,即使没有被加上静态方法装饰器。
image.png
通常来说,新式类开始实例化时,new()方法会返回cls(cls指代当前类)的实例,然后该类的init()方法作为构造方法会接收这个实例(即self)作为自己的第一个参数,然后依次传入new()方法中接收的位置参数和命名参数。
问题:当我们实现单例时,为了保证线程安全需要在内部加入锁
15.flask请求上下文和应用上下文
image.png
image.png
16.python类的继承
Python中的继承分为单继承和多继承
image.png
print A.mro
image.png
17.反射
反射
类的内置attr属性
18.迭代器协议实现斐波那契数列python
image.png
19.描述符
image.png
20。解释器和GIL锁
Cpython中存在全局解释器锁,作用在解释器上,锁的是线程,基于这个锁的存在导致同一进程中同一时刻只能有一个线程运行。