GIL全称Global Interpreter Lock(全局解释器锁)。GIL和Python语言没有任何关系,只是因为历史原因导致在官方推荐的解释器Cpython中遗留的问题。(多线程)每个线程在执行的过程中都需要先获取GIL,保证同一时刻只有一个线程可以执行代码,但是当遇到IO阻塞会自动的释放GIL锁,所以使用多线程还是比单线程的效率要高。如果想发挥多核CPU资源,可以使用多进程。为了避免受GIL的影响可以不用官方推荐的Cpython,或者用其他语言来实现,使用多进程。
计算密集型建议采用进程
IO密集型建议采用线程或者协程
浅拷贝是对一个对象的顶层(外层)拷贝,只是拷贝了引用,并没有拷贝内容。
变量的赋值是地址的引用,也算是一种浅拷贝。
深拷贝则是对一个对象深层(递归)的拷贝,保证了数据的独立性。
知识点:
可变类型:列表、字典
不可变类型:数字类型、字符串型、元组
- 如果是可变类型,浅拷贝只拷贝外层,而深拷贝是完全拷贝
- 如果是纯的不可变类型,那么无论是浅拷贝还是深拷贝,都只是指向同一个地址
- 如果不可变类型里面还存在可变类型,则浅拷贝是指向,而深拷贝则为完全拷贝
(了解)列表切片、字典的copy方法均属于浅拷贝
xx: 公有变量
_x: 单前置下划线,私有化属性或方法,from 模块 import *禁止导入,类对象和子类可以访问。
__xx:双前置下划线,避免与子类中的属性命名冲突,无法在外部直接访问(名字重整所以访问不到,_类名__xx)
__xx__:双前后下划线,用户名字空间的魔法对象或属性。例如:__init__ , __ 不要自己发明这样的名字。
xx_:单后置下划线,用于避免与Python关键词的冲突,不推荐使用。
import sys
sys.path # 返回查找模块的列表目录,列表中的路径的先后顺序代表了python解释器在搜索模块时的先后顺序。第一个元素返回的是一个空字符串表示当前目录。
sys.path.append('/home/itcast/xxx') # 在列表最后追加搜索目录
sys.path.insert(0, '/home/itcast/xxx') # 可以确保先搜索这个路径
from imp import reload
reaload(模块名)
(必须得先import 模块)
通过from 模块 import 变量,此时相当于给一个变量赋值,如果在程序中修改了变量的值就导致这个变量成了局部变量,跟其他模块就不共享了。如果多模块开发时想导入变量,建议使用import 模块名的方式,然后通过模块名.变量的方式去调用。
封装就是把方法和属性封装到类(类是抽象的,不能直接使用)的内部,只需要在类的外部,通过对象即可调用。继承实现了代码的重用。子类可以继承父类,并且可以继承多个父类即多继承,子类可以使用父类所拥有的属性和方法(除了私有属性和方法)。多态是以继承和重写父类方法为前提,增加了代码的灵活度,只是一种调用技巧。
多继承指的是子类继承多个父类,可以通过三种方式访问父类的方法:
父类名.父类方法(self):这种方式容易造成父类方法被调用多次的问题,而且一旦父类名称发生变化,子类调用的地方都需要修改。
super(指定某个类名, self).父类方法():从指定类名的MRO下一级开始调用
super().父类方法():按照MRO顺序查找上级父类的方法。
「方法解析顺序」(Method Resolution Order简称MRO)
可以通过类名.__MRO__属性查找出来当前类的调用顺序,其顺序由C3算法来决定,保证每一个类只调用一次。
单继承用哪种方式调用父类方法都可以,基本上无差别,但是建议super()的方式。
super()单继承只需要传父类参数,但是多继承必须传全部参数,可以使用多值参数。
在Python中一切皆对象,类是一个特殊的对象即类对象,描述类的属性称为类属性,它属于类。类属性在内存中只有一份,所有实例对象公用。在__init__外部定义。
实例属性用来描述类创建出来的实例对象,需要通过对象来访问,在各自对象的内存中都保存一份。在__init__方法内部定义
这三种方法都是保存在类的内存中,调用者不同。
实例方法由对象调用,至少一个self参数,self代表对象的引用。
类方法由类调用,至少一个cls参数,并且需要装饰器@classmethod修饰
静态方法由类调用,不需要参数,需要装饰器@staticmethod修饰
一种用起来像是使用的实例属性一样的特殊属性,可以对应于某个方法,通过使用property属性,能够简化调用者在获取数据的流程。
property属性的定义和调用要注意以下几点:
定义时,在实例方法的基础上添加 @property 装饰器;并且仅有一个self参数
调用时,无需括号,加上就错了。
经典类中的属性只有一种访问方式,其对应被 @property 修饰的方法,即只能读取。
新式类中的属性有三种访问方式,并分别对应了三个被@property、@方法名.setter、@方法名.deleter修饰的方法,分别对应读取、修改和删除属性的方法。
当使用类属性的方式创建property属性时,经典类和新式类无区别
property()方法有四个参数
第一个参数是方法名,调用 对象.属性 时自动触发执行方法
第二个参数是方法名,调用 对象.属性 = XXX 时自动触发执行方法
第三个参数是方法名,调用 del 对象.属性 时自动触发执行方法
第四个参数是字符串,调用 对象.属性.__doc__ ,此参数是该属性的描述信息
__doc__ 表示类的描述信息
__module__ 表示当前操作的对象在那个模块
__class__ 表示当前操作的对象的类是什么
__new__ 创建对象时为对象分配空间,在初始化方法__init__之前被调用
__init__ 初始化方法,通过类创建对象时,自动触发执行
__del__ 当对象在内存中被释放时,自动触发执行
__call__ 对象后面加括号,触发执行,例如对象()或者类名()()
__dict__ 类或对象中的所有属性
__str__ 在打印对象时,默认输出该方法的返回值(字符串)
任何实现了 __enter__() 和 __exit__() 方法的对象都可称之为上下文管理器,上下文管理器对象可以使用 with 关键字。Python 提供了 with 语法用于简化资源操作的后续清除操作,是 try/finally 的替代方法,实现原理建立在上下文管理器之上。
使用的with open(文件名) as f:这种语法可以在文件调用结束或者文件操作异常的时候自动关闭文件