1. GIL(全局解释器锁)
-
GIL是CPython解释器中存在的,一般解释器都是CPython,同一时刻只有一个线程在运行,而且不能利用CPU多核的特性,所以无法实现并行。
-
设置GIL锁
-
切换到一个线程执行
-
执行以下指令:
-
执行指定数量的代码
-
遇到延时(time.sleep、io操作、socket的recv、accept、content等)操作,线程让出控制权
-
-
释放GIL锁
-
切换出线程
-
重复上述步骤 所以,多线程和多进程、协程的应用场景:
- 计算(CPU)密集型:进程
- IO密集型:线程、协程
-
2. 深拷贝与浅拷贝
2.1 浅拷贝
浅拷贝就是拷贝对象的引用地址,内存地址不变 一般常见的浅拷贝有:
-
切片
-
list() 非数据类型转换
-
dict.copy() 字典拷贝
-
导入模块copy
import copy copy.copy()
浅拷贝不能拷贝不可变类型数据,不可变类型中存在可变数据也不进行拷贝
2.2 深拷贝
深拷贝就是拷贝对象的所有,拷贝引用地址,改变内存地址并且复制其中的数据
import copy
copy.deepcopy()
深拷贝不能拷贝不可变类型,但其中只要存在一个可变类型的数据,就可做深拷贝
3.私有化
- _x:单前置下划线,表示私有属性或方法,from xxx import * 不可以导入此类属性或方法,但其类对象和子类可以访问
- __xx:双前置下划线,私有化xx,一般避免与子类中的属性命名冲突,无法在外部直接访问
- xx:双前后下划线,用户名、或系统魔法方法
4. Python mro
4.1 什么是mro
mro即method resolution order(方法解释顺序),解决Python多继承出现的二义性问题: 例:
class A():
def f(self):
pass
class B(A):
def f(self):
pass
class C(A, B):
def f(self):
pass
class D(B, C):
def f(self):
pass
class E(C, D):
def f(self):
pass
Python中会产生这样的问题,利用C3算法可以确定子类中继承方法的顺序,该序列保存在子类对象__mro__中
4.2 快速确定mro顺序
- 确定继承关系
- 画出继承关系图
class D(object):
pass
class E(object):
pass
class F(object):
pass
class C(D, F):
pass
class B(E, D):
pass
class A(B, C):
pass
if __name__ == '__main__':
print(A.__mro__)
- 左边优先原则
- 上下无法确定谁在左边,下级优先
5. *args,**kwargs
5.1 函数声明:
def func(*args, **kwargs)
- *args可以接收不定长参数
- **kwargs可以接受关键字参数
5.2 函数调用
def func(*args, **kwargs):
pass
func(*args, **kwargs)
此时表示拆包
6. Python中类方法、实例方法、静态方法有何区别?
例:
class Test(object):
def __init__(name,age):
self.name = name
self.age = age
@classmethod
def test1(cls,name): # cls,类对象
obj = cls(name,18) # 类对象可以创建实例对象
@staticmethod
def test2():
return age<18 and len(name)>6
def test3(self): # self,实例对象
pass
test = Test("sss",19)
- 类方法:是类对象的方法,在定义时需要在上方使用"@classsmethod"进行装饰,形参为cls,表示类对象,类对象和实例对象都可调用; 可以利用实例方法中cls即类对象创建一份实例对象,扩充的初始化__init__方法的参数限制
- 实例方法:是类实例化对象的方法,只有实例对象可以调用,形参为self,指代对象本身;
- 静态方法:是一个任意函数,在其上方使用@staticmethod进行装饰,可以用对象直接调用,静态方法实际上跟该类没有太大关系,一般作为类提供的工具方法存在
7. property属性
通过property将类中的方法提升为一个属性,隐藏具体逻辑,对外只需像属性一样访问即可调用方法并获得返回值,简化调用者获取数据的流程
- 装饰器的方式创建
class Date(objecct):
def __init__(self):
self.__name = "sss"
@property
def name(self):
return self.__name
@name.setter
def name(self, value):
self.__name = value
- 类属性来创建
class Foo(object):
def get_bar(self):
print("getter...")
return "www"
def set_bar(self, value):
"""必须两个参数"""
print("setter...")
return "set value" + value
def del_bar(self):
print("deleter...")
return "www"
如果代码考虑Python版本的兼容性,用类属性的方式创建,否则优先考虑装饰器的方式
8. 上下文管理器、with
系统资源如文件、数据库连接、socket而言,应用程序打开这些资源并执行完业务逻辑之后,必须做的一件事就是要关闭(断开)该资源。为了避免每次都手动去关闭这些资源,可以使用with关键字,比如:
with open("output.txt", "r") as f:
f.write("python")
with后面紧挨的语句返回的对象必须是一个上下文管理器,任何实现了__enter__()和__exit__()方法的对象都可称为上下文管理器。 例:
class SocketManager():
def __init__(self, ip, port):
self.addr = (ip, port)
def __enter__(self):
self.tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.tcp_socket.connect(self.addr)
return self.tcp_socket
def __exit__(self, exc_type, exc_val, exc_tb):
self.tcp_socket.close()
with SocketManager("127.0.0.1", 7890) as s:
s.recv(1024)
s.send(b"hello")
如果中间遇到异常close方法也会被调用
- with会判断后面的语句返回值是不是一个上下文管理器
- 如果该对象是上下文管理器,调用该对象的__enter__()方法,并交给as后面的变量
- 使用该变量进行业务逻辑操作,完事后,会自动调用该对象的__exit__()方法去释放资源