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 該類的建構函式,但是你要為別人提供乙個該類的唯一物件,所以你要在該類中定義乙個靜態的方法返回本類物件。設計模式 解決某一問題最行之有效的方法 單例設計模式 解決乙個類在記憶體只存在乙個物件 想...