list是可变数据类型 tuple是不可变数据类型,list可以在原内存地址上修改值
扩展:容器是一种把多个元素组织在一起的数据结构
几种容器类型:list、tuple、dict、set
list:有序项目集合、可以存放任何数据类型、可变数据类型(可以在原内存地址上修改值)
tuple:有序项目集合、可以存放任何数据类型、不可变数据类型
dict:无序项目集合、可变数据类型、key是唯一的,天生去重
set:无序项目集合、可变数据类型、去重、只能存放可hash对象(不可变数据类型)
PEP8规范是python的编码风格指南
1、使用4个空格的缩进,不要使用制表符tab键
2、一行不超过79个字符,\续行符
3、注释独占一行
4、运算符的周围都用空格,逗号后面用空格
以引用计数为主,分代回收、标记清除为辅的垃圾回收方式进行内存回收,并且还引入小整数缓冲池和常见简单字符串驻留区的内存缓存池机制
a、引用计数:当对象的引用计数为0的时候,销毁对象
当有新的引用指向的时候,引用计数+1
当有无效的引用发生的时候,引用计数-1
循环引用:引用计数无法解决循环引用的问题,用垃圾回收去处理
获取引用计数:使用getrefcount - 1
b、垃圾回收:当对象的引用计数降为0,可以被垃圾回收
(垃圾回收)gc机制:1、找到无用的垃圾资源 --》 2、清除垃圾
三种情况触发垃圾回收:
1、调用gc.collect()
2、gc达到阈值(分代回收):存活时间越久的对象,越不可能在后面的程序中变成垃圾
分代回收:新建对象为0代成员,0代成员经历10次垃圾回收依然存活升级为1代成员,1代成员经历10次回收依然存活升级为2代成员,2代成员最高级,扫描0代成员10次才会扫描1代成员1次,扫描1代成员10次才会扫描2代成员1次
gc.get_threshold() 结果是(700,10,10)
3、程序退出时
c、内存池机制:小整数缓冲池[-5,256]、常用字符串驻留区
小整数缓冲池:减少频繁创建和销毁的开销(a=1, b=1, c=1 指向的都是同一个对象)
字符串驻留区:在驻留区里下次使用直接从驻留区里面拿,不会再创建新的空间了
内存泄露:有一部分内存无法被回收释放,程序又无法访问
内存溢出:内存不够用,程序需要的内存大于实际内存
1、psutil 能够获取系统运行的CPU、内存、磁盘、网络等信息,主要应用于系统监控
2、paramiko 可以实现远程连接服务器,对服务器进行一些远程操作
我写了一个监控cpu、内存等使用情况的脚本,然后使用paramiko模块写了一个脚本,这个脚本的内容是连接到远程机器,上传监控脚本到远程机器,并且执行这个监控脚本,这样我在本机执行自己写的paramiko脚本就可以实现远程监控功能
3、pymysql 在python中连接mysql
4、logging 日志模块
四大组件:1、日志器 Logger 2、处理器 Handler 3、过滤器 Filter 4、格式器 Formatter
5、requests 请求网站上的东西,爬取百度图片
多进程:multiprocessing和fork 多线程:threading
线程:操作系统进行调度的最小单位
进程:正在运行的程序,是系统进行资源分配的最小单位
进程包含线程 一个进程至少包含一个线程
进程与线程的关系
#1、一个进程内可以有一个以上的线程,这些线程都是共享这些进程的内存空间的。
#2、不同进程之间内存空间都是独立的。
#3、创建新的线程很简单,创建一个新的进程都需要对其父进程进行一次克隆。
#4、一个线程可以控制和操作同一个进程里的其他线程,进程只能操作子进程。
#5、一个主线程改变,可能会影响其他进程,改变父进程不会影响子进程。
进程的三种状态
#进程的三种状态 : 就绪、运行、阻塞、(新建、终止)
#就绪 --》 运行 (进程调度)
#运行 --》 就绪 (时间片到)
#运行 --》 阻塞 (等待某件事情比如I/O请求)
#阻塞 --》 就绪 (等待的事情发生/完成 比如I/O结束)
孤儿进程与僵尸进程
#孤儿进程:一个父进程退出,子进程还在运行,那么这个子进程就会成为孤儿进程
#孤儿进程会被pid为1的进程所收养
#僵尸进程:子进程退出,父进程没有响应。父进程没有去调用wait()或者waitpid()去获取子进程的状态
#子进程的进程控制块依然保存在系统中,这种进程称之为僵尸进程
全局解释器锁
Cpython的历史遗留问题;保证同一时刻同一个进程内只有一个线程可以执行代码
GIL不能解决资源争用的问题
#由于GIL锁的限制,所以多线程不适合计算型任务,而更适合IO型任务(IO阻塞多的时候使用多线程)
#计算密集型任务:用CPU、计算 => 多进程
#IO密集型任务:网络IO(抓取网页数据)、磁盘操作(读写文件)、键盘输入… => 多线程+多进程
协程是一种用户态的轻量级线程,协程的调度完全由用户控制
协程主要用于网络爬虫和网络请求
flask 轻、灵活、可扩展性强、适合开发web服务的API
django 重、灵活度不高、大规模应用
容器里面包含可变数据类型容器的时候,才会有深浅的区别
深拷贝不会影响原来的拷贝对象 --》因为拷贝的是每一层的值
浅拷贝可能会影响原来的拷贝对象 --》拷贝的是第一层的地址、引用
只有deepcopy才是深拷贝
无序字典:字典底层是维护一张哈希表,可以把哈希表看成一个列表,哈希表中的每一个元素又存储了哈希值(hash)、键(key)、值(value)3个元素。
python列表基于数组实现,python动态扩容数组实现列表的可变长度。
python遇到异常就会退出整个程序,我们如果不希望这种情况出现,就可以引入异常处理机制,对异常做特殊处理
try.... except 异常捕获:1、保证程序发生异常时不退出 2、对异常做特殊处理
raise 手动触发异常
常见的异常
NameError 标识符找不到,没有被定义
IndexError 下标异常
AttributeError 属性异常
ValueError 参数传递类型不正确
断言异常
面向对象着重于谁去做,迭代更新方便、方便管理
类的三大特性:封装、继承、多态
区别:类型上的区别、在继承顺序上的区别 最大区别
魔术方法:不需要手动去调用,在某些特定场景下自动执行,有特殊含义的方法
__new__ 创建实例
__init__ 初始化实例
析构方法__del__
调用方法__call__ 有这个属性的对象称为callable对象
把实例化后的对象当作函数自动调用
对象的描述信息 __str__和__repr__
对象以字典的形式去设置或获取参数:__getitem__、__setitem__、__delitem__
装饰器是这样一种设计模式:如果一个类(函数)希望添加其他类(函数)的一些功能,而不希望通过继承或是直接修改源代码实现,那么可以使用装饰器模式
装饰器:装饰器的本质就是闭包,在不改变函数或者类的源代码的基础上,添加额外功能
闭包是什么?
形成闭包之后,闭包函数会得到一个非空的__closure__属性
闭包条件
1、必须有一个内嵌函数
2、内函数必须引用外函数的变量
3、外函数必须返回内函数
什么是迭代器?
任何实现了__iter__()和__next__()都是迭代器
iter() 返回自身
next() 不断的返回下一个值
什么是生成器?
生成器是一种特殊的迭代器
就是为了写迭代器更加方便优雅,不需要手动实现__iter__和__next__方法
生成器的两种形式:生成器表达式、生成器函数
使用迭代器的好处:迭代器是一个懒加载模式,用的时候才加载
使用生成器的好处:生成器不需要占用那么多内存,并且不用手动生成__iter__方法和__next__方法
可迭代对象与迭代器的区别:可迭代对象:实现了__iter__方法,并且该方法返回一个迭代器,这样的一个对象就是可迭代对象;可迭代对象没有__next__方法
定义一个生成器?
生成器表达式、生成器函数 yield关键字