1. 程式人生 > >【python】單例設計模式

【python】單例設計模式

動作 font 初始 記錄 sta pan dash sicp rgs

1. 定義

  • 目的——讓類創建的對象,在系統中只有唯一的實例。
  • 每一次執行新建對象操作,返回的都是同一個對象。

2. __new__ 方法

  使用 classname() 創建對象時,Python 的解釋器首先會調用 __new__ 方法為對象分配內存空間。

  __new__ 方法是 object 基類提供的內置靜態方法,主要作用有兩個:

  1. 為對象分配內存空間
  2. 返回對象的引用

  Python 解釋器獲得對象的引用後,將引用作為第一個參數 self,傳遞給 __init__方法

重寫 __new__ 方法

  • 一定要 return super().__new__(cls),否則 Python 解釋器得不到分配了空間的對象引用,就不會調用對象的初始化方法。
    class
    MusicPlayer(object): def __new__(cls, *args, **kwargs): return super().__new__(cls) def __init__(self): print("初始化音樂播放對象") player = MusicPlayer() print(player)

3. 實現單例

讓系統中只存在唯一實例

class MusicPlayer(object):

    # 定義類屬性記錄單例對象引用
    instance = None

    
def __new__(cls, *args, **kwargs): # 1. 判斷類屬性是否已經被賦值 if cls.instance is None: cls.instance = super().__new__(cls) # 2. 返回類屬性的單例引用 return cls.instance
  • 每次使用 classname() 創建對象時,Python 解釋器將自動調用兩個方法:
  1. __new__ 分配空間
  2. __init__ 對象初始化

  因此完成對 __new__ 方法的重寫後,每次新建對象將會得到第一次創建對象時的引用,但初始化方法每次還會被調用。

只執行一次初始化工作

  實現辦法:定義一個類屬性 init_flag 標記是否執行過初始化

"""python單例"""


class MusicPlayer(object):

    # 記錄第一個被創建對象的引用
    instance = None

    # 記錄是否執行過初始化動作
    init_flag = False

    def __new__(cls, *args, **kwargs):

        # 1. 判斷類屬性是否是空對象
        if cls.instance is None:
            # 2. 調用父類的方法,為第一個對象分配空間
            cls.instance = super().__new__(cls)

        # 3. 返回類屬性保存的對象引用
        return cls.instance

    def __init__(self):

        if not MusicPlayer.init_flag:
            print("初始化音樂播放器")

            MusicPlayer.init_flag = True

【python】單例設計模式