GIL是CPython解釋器中存在的,通常解釋器都是CPython,同一時刻只有一個線程在運行,並且不能利用CPU多核的特性,因此沒法實現並行。python
設置GIL鎖算法
切換到一個線程執行數據庫
執行如下指令:多線程
執行指定數量的代碼socket
遇到延時(time.sleep、io操做、socket的recv、accept、content等)操做,線程讓出控制權tcp
釋放GIL鎖函數
切換出線程工具
重複上述步驟 因此,多線程和多進程、協程的應用場景:spa
淺拷貝就是拷貝對象的引用地址,內存地址不變 通常常見的淺拷貝有:線程
切片
list() 非數據類型轉換
dict.copy() 字典拷貝
導入模塊copy
import copy
copy.copy()
複製代碼
淺拷貝不能拷貝不可變類型數據,不可變類型中存在可變數據也不進行拷貝
深拷貝就是拷貝對象的全部,拷貝引用地址,改變內存地址而且複製其中的數據
import copy
copy.deepcopy()
複製代碼
深拷貝不能拷貝不可變類型,但其中只要存在一個可變類型的數據,就可作深拷貝
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__中
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__)
複製代碼
def func(*args, **kwargs)
複製代碼
def func(*args, **kwargs):
pass
func(*args, **kwargs)
複製代碼
此時表示拆包
例:
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)
複製代碼
經過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版本的兼容性,用類屬性的方式建立,不然優先考慮裝飾器的方式
系統資源如文件、數據庫鏈接、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方法也會被調用