python 單例模式,一個類只能生成唯一的一個實例,重寫__new__方法詳解


單例:一個類只能生成唯一的一個實例

 

每個類只要被實例化了,他的私有屬性 '_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實例.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM