閱讀本文大約須要 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
未寫完,下一次更新補上