單例:一個類只能生成唯一的一個實例
每個類只要被實例化了,他的私有屬性 '_instance'就會被賦值,這樣理解對嗎
對
#方法1,實現__new__方法
#並在將一個類的實例綁定到類變量_instance上,
#如果cls._instance為None說明該類還沒有實例化過,則實例化該類,並返回實例對象
#如果cls._instance不為None,直接返回已經實例化了的實例對象
cls._instance
#super(Singleton, cls)是object 的意思
#coding=utf-8
class Singleton(object):
def __new__(cls, *args, **kw):
if not hasattr(cls, '_instance'):
orig = super(Singleton, cls)
cls._instance = orig.__new__(cls, *args, **kw)
#cls._instance = object.__new__(cls, *args, **kw) #等價上一句
return cls._instance
class MyClass(Singleton):
a = 1
one = MyClass()
two = MyClass()
two.a = 3
print one.a
#3
#one和two完全相同,可以用id(), ==, is檢測
print id(one)
#40579184
print id(two)
#40579184
print one == two
#True
print one is two
#True
c:\Python27\Scripts>python task_test.py
3
40579184
40579184
True
True
程序解釋:
#coding=utf-8
class Singleton(object):
def __new__(cls, *args, **kw):
if not 判斷此類是否存在類變量_instance“”
如果不存在,則生成一個Singleton的實例
並且賦值給類變量_instance
下面返回類變量中保存的實例對象
return cls._instance
#coding=utf-8
class Singleton(object):
def __new__(cls, *args, **kw):
#如果不存在類變量_instance,則執行if下的子句
if not hasattr(cls, '_instance'):
#下面兩句,表示使用object.__new__方法生成了Singleton的一個實例
#super(Singleton, cls)是object 的意思
orig = super(Singleton, cls)#這句參考下邊的調用基類構造方法,沒有后邊的.__init…,
#應該就是表示基類object,只不過是把類名賦值給orig了
cls._instance = orig.__new__(cls, *args, **kw)#從下邊可以看到改成
#cls._instance = object.__new__(cls, *args, **kw),結果是一樣的
#返回類對象中保存的實例對象
return cls._instance
‘’’
#調用基類構造方法例子
class C(A):
def __init__(self):
super(C,self).__init__()#調用基類構造方法
‘’’
c:\Python27\Scripts>python task_test.py
3
40403056
40403056
True
True
改成另一種調用基類__new__的方法:
#coding=utf-8
class Singleton(object):
def __new__(cls,*args,**kw):
if not hasattr(cls,'_instance'):
#orig=super(Singleton,cls)
cls._instance=object.__new__(cls,*args,**kw)
return cls._instance
class MyClass(Singleton):
a=1
one=MyClass()
two=MyClass()
two.a=3
print one.a
print id(one)
print id(two)
print one==two
print one is two
c:\Python27\Scripts>python task_test.py
3
41189456
41189456
True
True
后期添加注釋代碼:
#coding=utf-8
class Singleton(object):
def __new__(cls,*args,**kw):
if not hasattr(cls,'_instance'):
orig=super(Singleton,cls)
cls._instance=orig.__new__(cls,*args,**kw)
#打印返回:type <class '__main__.MyClass'>
print "type", type(cls._instance)#返回類對象的類型
return cls._instance
class MyClass(Singleton):
a=1
one = MyClass()#返回一個類的實例對象
two = MyClass()#返回一個同一個實例對象
#返回:one: <__main__.MyClass object at 0x027730D0>
print "one:",one
#返回也是:two: <__main__.MyClass object at 0x027730D0>
print "two:",two
two.a = 3
print one.a
#3
#one和two完全相同,可以用id(), ==, is檢測
print id(one)
#29097904
print id(two)
#29097904
print one == two
#True
print one is two
#True
結果:
c:\Python27\Scripts>python task_test.py
type <class '__main__.MyClass'>
one: <__main__.MyClass object at 0x027A30D0>
two: <__main__.MyClass object at 0x027A30D0>
3
41562320
41562320
True
True
hasattr(cls,’_instance’):判斷對象中是否包含這個屬性-類變量
類實例對象里是否有這個類變量
單例用處:
http://blog.csdn.net/tanyujing/article/details/14160941
單例模式的應用場景:
1. Windows的Task Manager(任務管理器)就是很典型的單例模式(這個很熟悉吧),想想看,是不是呢,你能打開兩個windows task manager嗎? 不信你自己試試看哦~
2. windows的Recycle Bin(回收站)也是典型的單例應用。在整個系統運行過程中,回收站一直維護着僅有的一個實例。
3. 網站的計數器,一般也是采用單例模式實現,否則難以同步。
4. 應用程序的日志應用,一般都何用單例模式實現,這一般是由於共享的日志文件一直處於打開狀態,因為只能有一個實例去操作,否則內容不好追加。
5. Web應用的配置對象的讀取,一般也應用單例模式,這個是由於配置文件是共享的資源。
6. 數據庫連接池的設計一般也是采用單例模式,因為數據庫連接是一種數據庫資源。數據庫軟件系統中使用數據庫連接池,主要是節省打開或者關閉數據庫連接所引起的效率損耗,這種效率上的損耗還是非常昂貴的,因為何用單例模式來維護,就可以大大降低這種損耗。
7. 多線程的線程池的設計一般也是采用單例模式,這是由於線程池要方便對池中的線程進行控制。
8. 操作系統的文件系統,也是大的單例模式實現的具體例子,一個操作系統只能有一個文件系統。
9. HttpApplication 也是單位例的典型應用。熟悉ASP.Net(IIS)的整個請求生命周期的人應該知道HttpApplication也是單例模式,所有的HttpModule都共享一個HttpApplication實例.