1. 程式人生 > >七、面向對象之單例設計模式

七、面向對象之單例設計模式

lse 怎麽 pri style 重寫 sel pan war clas

一、"""單例設計模式:通俗的講就是單個實例對象
設計模式:前人在工作中,為了做需求寫代碼積累的一種代碼設計思想,我們根據套路來就行了
>>>>>>>
之前講過的創建類實例對象,工作原理是這樣的---調用類創建對象,解釋器會自動調用__new__這個內置的靜態方法為對象分配內存空間
,然後返回這個對象,再將這個對象的引用傳給__init__初始化方法進行初始化。這是工作原理,但是在創建多個對象時,給對象分配
內存空間的內存地址是不一樣的,也就是多個實例,接下來單例就是要將創建多個對象時,分配的內存空間的內存地址始終是唯一一個,這就叫單例
"""
這幅圖是描述調用類創建對象時的工作原理:
技術分享圖片

實現單例的代碼:
class Person(object):
    instance_neicun = None  # 用類屬性記錄創建對象時的內存地址

    def __new__(cls, *args, **kwargs):  # 重寫new方法
        if cls.instance_neicun is None:
             cls.instance_neicun = super().__new__(cls)  # 用一個變量接收object類中new方法返回的內存地址,new是一個特殊的靜態
                                                           #
方法,調用時需要傳遞cls參數 return cls.instance_neicun # new方法需要返回一個對象, def __init__(self): print(初始化開始...) a = Person() print(a) b = Person() print(b)

輸出結果:
初始化開始...
<單例設計模式.Person object at 0x0000000001730748>
初始化開始...
<單例設計模式.Person object at 0x0000000001730748>
此時你會發現,我創建倆個對象時,內存地址都是一樣的!

二、上面的代碼你會發現,初始化內容每調用一次就會輸出一次,那麽如果只要輸出一次怎麽做呢?只需要將上述代碼做一點修改就可以了
class Person(object):
    instance_neicun = None  # 用類屬性記錄創建對象時的內存地址
    instance_flag = False  # 是否執行過初始化方法的標記

    def __new__(cls, *args, **kwargs):  # 重寫new方法
        if cls.instance_neicun is None:
             cls.instance_neicun = super().__new__(cls)  # 用一個變量接收object類中new方法返回的內存地址,new是一個特殊的靜態
                                                           #方法,調用時需要傳遞cls參數

        return cls.instance_neicun  # new方法需要返回一個對象,

    def __init__(self):
        # 判斷如果初始化方法被調用過一次,就直接返回
        if Person.instance_flag is True:
            return
        # 如果沒有調用過,就進行初始化
        print(初始化開始...)
        # 修改標記
        Person.instance_flag = True
        
        
a = Person()
print(a)
b = Person()
print(b)

輸出結果:
初始化開始...
<單例設計模式.Person object at 0x000000000170F668>
<單例設計模式.Person object at 0x000000000170F668>
此時你會發現,創建倆個對象,只輸出了一個初始化內容

 

 

七、面向對象之單例設計模式