python深刻

1. GIL(全局解釋器鎖)

  • GIL是CPython解釋器中存在的,通常解釋器都是CPython,同一時刻只有一個線程在運行,並且不能利用CPU多核的特性,因此沒法實現並行。python

    1. 設置GIL鎖算法

    2. 切換到一個線程執行數據庫

    3. 執行如下指令:多線程

      • 執行指定數量的代碼socket

      • 遇到延時(time.sleep、io操做、socket的recv、accept、content等)操做,線程讓出控制權tcp

    4. 釋放GIL鎖函數

    5. 切換出線程工具

    6. 重複上述步驟 因此,多線程和多進程、協程的應用場景:spa

    • 計算(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順序

  1. 肯定繼承關係
  2. 畫出繼承關係圖
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將類中的方法提高爲一個屬性,隱藏具體邏輯,對外只需像屬性同樣訪問便可調用方法並得到返回值,簡化調用者獲取數據的流程

  1. 裝飾器的方式建立
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
複製代碼
  1. 類屬性來建立
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方法也會被調用

  1. with會判斷後面的語句返回值是否是一個上下文管理器
  2. 若是該對象是上下文管理器,調用該對象的__enter__()方法,並交給as後面的變量
  3. 使用該變量進行業務邏輯操做,完過後,會自動調用該對象的__exit__()方法去釋放資源
相關文章
相關標籤/搜索