阅读本文大约须要 7 分钟。
LEGB 指的是 Python 中的变量做用域问题,其中编程
L:local 局部变量,仅存在函数内部,其存储位置位于栈中,其生命周期在函数结束时就会被释放。多线程
E:enclosing 外部做用域变量,常见于闭包函数,也就是嵌套函数中的上一层函数变量。其生命周期在整个闭包函数结束时会被释放。闭包
G:global 全局变量,做用于整个程序,其存储位置位于全局数据区中,其生命周期在程序销毁时就被释放。app
B:builtins 内建模块变量,其存储于内置变量命名空间。函数式编程
变量查找顺序: 函数
L-E-G-B源码分析
示例:性能
def func(): a = b = 1 def internal_func(c): if a+b == c: print('True') else: print('False') test = func() test(2) # 结果为 True
闭包函数做为函数式编程中的一种,当含有如下几点时,即可称它为一个闭包函数。优化
闭包函数能够大幅提升代码复用性,使得代码性能大幅提升。ui
浅拷贝
copy 模块下的 copy() 方法,实现一个对象的浅拷贝,list 下的分割也是一种浅拷贝,
示例:
import copy a = [1, 2, [3, 4]] b = copy.copy(a) a == b a is b # 结果为 True,False e = [1, 2, [3, 4]] f = e[2] h = e[2][:] f == h f is h # 结果为 True,False
浅拷贝只会拷贝对象的第一层引用,若是是复合类型,如 list 里面嵌套 list,则当内嵌 list 发生变化时,通过浅拷贝出来的对象,也会发生变化。
示例:
import copy a = [1, 2, [3, 4]] b = copy.copy(a) a == b a is b # 结果为 True,False c = copy.copy(a) a[1] = 0 print(a) print(c) # 结果为 a = [1, 0, [3, 4]], c = [1, 2, [3, 4]] a[2].append(5) print(a) print(c) # 结果为 a = [1, 0, [3, 4, 5]], c = [1, 2, [3, 4, 5]]
深拷贝
深拷贝将拷贝对象里全部引用所有拷贝,生成一个全新的对象。
示例:
import copy a = [1, 2, 3, 4] b = copy.deepcopy(a) a == b a is b # 结果为 True,False
深、浅拷贝会根据拷贝对象的数据类型,决定是否开辟新的内存空间来存放拷贝出来的新对象。
import copy a = [1, 2, 3, 4] # list 可变类型 b = copy.copy(a) a == b a is b # 结果为 True,False c = (1, 2, 3, 4) # tuple 不可变类型 d = copy.copy(c) e = copy.deepcopy(c) c == d c is d c is e # 结果为 True,True, True
[深拷贝源码分析](),先占坑,还未写。
Python 中经过将对象进行 HASH 来判断该对象是哪一种类型,可 HASH 的为不可变类型,不可 HASH 的为可变类型。其中常见的几种以下所示:
可变类型:List,dict,set
不可变类型:int,float,string,tuple,frorzenset
也可经过是否含有__hash__()
方法,判断该对象为什么种类型,拥有该方法的为不可变类型,相反为可变类型。
首先经过类的魔法方法__new__()
来建立一个实例,再经过魔法方法__init__()
来对这个实例初始化,最终删除一个实例时,Python 根据该实例的「引用计数」来判断是否释放该实例所占用的内存,当该实例的引用计数为 0 时,__del__()
方法才会被调用,__del__()
方法的不等同于del
。
单例是指一个类的实例有且只有一个。通常在一个类只须要使用一次以后便不在使用时使用。
实现方式:
使用__new__()
方法
class Singleton(): is_instance = None def __new__(cls): if not cls.is_instance: cls.is_instance = super().__new__(cls) return cls.is_instance return cls.is_instance s = Singleton() g = Singleton() print(s is g) # 结果为 True
使用装饰器
def Singleton01(cls): is_instance = {} def get_instance(*args, **kwargs): if not is_instance: is_instance[cls] = cls() return is_instance[cls] return is_instance[cls] return get_instance @Singleton01 class Myclass(): pass s = Myclass() g = Myclass() print(s is g) # 结果为 True
多线程下实现单例
class Singleton02(): is_instance = None is_lock = threading.Lock() def __new__(cls): with cls.is_lock: if not cls.is_instance: cls.is_instance = super().__new__(cls) return cls.is_instance return cls.is_instance s = Singleton() g = Singleton() print(s is g) # 结果为 True
多线程优化
class Singleton03(): is_instance = None is_lock = threading.Lock() def __new__(cls): # 单例判断提早,只在第一次判断时加锁,避免无心义的加锁解锁 if not cls.is_instance: with cls.is_lock: cls.is_instance = super().__new__(cls) return cls.is_instance return cls.is_instance s = Singleton03() g = Singleton03() print(s is g) # 结果为 True
未写完,下一次更新补上