物件導向2 類例項化與單例模式

2022-07-28 00:45:16 字數 3012 閱讀 2136

class foo(object):

def __init__(self,x):

self.x = x

f = foo(x)

>>>foo.__class__

所以foo是型別type的乙個物件,foo是乙個類,但是python中的類也是物件!類、函式、方法以及例項都是物件,並且無論何時你將一對括號放在它們的名字後面時,就會呼叫它們的__call__方法。foo是型別type的乙個物件並且呼叫__call__返回乙個foo類的物件

常規類的例項化大致等同於:

def __call__(obj_type, *args, **kwargs):

obj = obj_type.__new__(*args, **kwargs)

if obj is not none and issubclass(obj, obj_type):

obj.__init__(*args, **kwargs)

return obj

__new__方法為物件分配了記憶體空間,構建它為乙個「空"物件然後__init__方法被呼叫來初始化它。

總的來說:

foo(*args, **kwargs)等價於foo.__call__(*args, **kwargs)

既然foo是乙個type的例項,foo.__call__(*args, **kwargs)實際呼叫的是type.__call__(foo, *args, **kwargs)

type.__call__(foo, *args, **kwargs)呼叫type.__new__(foo, *args, **kwargs),然後返回乙個物件。

obj隨後通過呼叫obj.__init__(*args, **kwargs)被初始化。

obj被返回。

詳細:定義:確保某個類只有乙個例項,而且自行例項化並向整個系統提供這個例項

場景:1.需要頻繁的例項化和銷毀的物件;

​ 2.有狀態的工具類物件

​ 3.頻繁訪問資料庫或檔案物件

例如:多執行緒的執行緒池的設計

​ **的計數器,一般也是採用單例模式實現,否則難以同步。

​ 資料庫連線池的設計一般也是採用單例模式。

優點

1.在單例模式中,活動的單例只有乙個例項,對單例類的所有例項化得到的都是相同的乙個例項。這樣就 防止其它物件對自己的例項化,確保所有的物件都訪問乙個例項

2.單例模式具有一定的伸縮性,類自己來控制例項化程序,類就在改變例項化程序上有相應的伸縮性。

3.提供了對唯一例項的受控訪問。

4.由於在系統記憶體中只存在乙個物件,因此可以 節約系統資源,當需要頻繁建立和銷毀的物件時單例模式無疑可以提高系統的效能。

5.允許可變數目的例項。

6.避免對共享資源的多重占用。

缺點:1.不適用於變化的物件,如果同一型別的物件總是要在不同的用例場景發生變化,單例就會引起資料的錯誤,不能儲存彼此的狀態。

2.由於單利模式中沒有抽象層,因此單例類的擴充套件有很大的困難。

3.單例類的職責過重,在一定程度上違背了「單一職責原則」。

4.濫用單例將帶來一些負面問題,如為了節省資源將資料庫連線池物件設計為的單例類,可能會導致共享連線池物件的程式過多而出現連線池溢位;如果例項化的物件長時間不被利用,系統會認為是垃圾而被**,這將導致物件狀態的丟失。

建立單例

方法1:metaclass

class singleton(type):

def __init__(cls, name, bases, dict):

super(singleton, cls).__init__(name, bases, dict)

cls.instance = none

def __call__(cls,*args,**kw):

if cls.instance is none:

cls.instance = super(singleton, cls).__call__(*args, **kw)

return cls.instance

class myclass(object,metaclass=singleton):

pass

'''#python2中

class myclass(baseclass)

__metaclass__ = single #屬性 __metaclass__,其用來表示該類由誰來例項化建立

'''

方法2:裝飾器

def singleton(class_):

instances = {}

def getinstance(*args, **kwargs):

if class_ not in instances:

instances[class_] = class_(*args, **kwargs)

return instances[class_]

return getinstance

@singleton

class myclass(object): #python2中: class myclass(baseclass):

pass

#經過裝飾器修飾,增加了判斷的功能,如果該類例項化過,例項的物件就會被新增在instance字典中,再次例項化,將從字典中返回

更多方法:

物件導向 單例模式

設計模式 解決某一類問題行之有效的解決辦法 思想 單例 singleton 設計模式 學習設計模式必須先弄清楚它是解決什麼問題的。單例是解決什麼問題的呢?可以保證乙個類的物件唯一性。場景 比如多個程式都要使用乙個配置檔案中的資料,而且要實現資料共享和交換。必須要將多個資料封裝到乙個物件中。而且多個程...

物件導向 單例設計模式

單例設計模式 就是保證該類在程式中只能存在乙個物件,所以不能讓別人例項化該類,所以要私有化 private 該類的建構函式,但是你要為別人提供乙個該類的唯一物件,所以你要在該類中定義乙個靜態的方法返回本類物件。設計模式 解決某一問題最行之有效的方法 單例設計模式 解決乙個類在記憶體只存在乙個物件 想...

物件導向 單例設計模式

單例設計模式 就是保證該類在程式中只能存在乙個物件,所以不能讓別人例項化該類,所以要私有化 private 該類的建構函式,但是你要為別人提供乙個該類的唯一物件,所以你要在該類中定義乙個靜態的方法返回本類物件。設計模式 解決某一問題最行之有效的方法 單例設計模式 解決乙個類在記憶體只存在乙個物件 想...