用decorator實現python單例模式

來源:互聯網
上載者:User

在 python 裡實現單例模式有許多方法,個人覺得還是基於 decorator 的方法最優雅。

從 stackoverflow 上找到一個實現,我將它改成了安全執行緒的,記錄如下:

import threadingclass Singleton:    """    A class to ease implementing singletons.    This should be used as a decorator -- not a metaclass -- to the    class that should be a singleton.    The decorated class can define one `__init__` function that    takes only the `self` argument. Other than that, there are    no restrictions that apply to the decorated class.    To get the singleton instance, use the `Instance` method. Trying    to use `__call__` will result in a `TypeError` being raised.    Limitations: The decorated class cannot be inherited from.    """    def __init__(self, decorated):        self._decorated = decorated        self.lock = threading.Lock()    def Instance(self):        """        Returns the singleton instance. Upon its first call, it creates a        new instance of the decorated class and calls its `__init__` method.        On all subsequent calls, the already created instance is returned.        """        try:            return self._instance        except AttributeError:            self.lock.acquire()            try:                return self._instance            except AttributeError:                self._instance = self._decorated()                return self._instance            finally:                self.lock.release()                def __call__(self):        raise TypeError('Singletons must be accessed through `Instance()`.')    def __instancecheck__(self, inst):        return isinstance(inst, self._decorated)

使用時,只要未需要實現 singleton 的類添加一個 decorator 就可以了,如下:

@Singletonclass MySingletonClass: passs1 = MySingletonClass.Instance()s2 = MySingletonClass.Instance()

s1 和 s2 就是相同的執行個體。

附上一個簡單的 testcase:

import unittestfrom singleton import Singleton@Singletonclass A: passclass TestSingleton(unittest.TestCase):    def testSingleton(self):        a = A.Instance()        aa = A.Instance()        self.assertTrue(a is aa)            def testSingletonCall(self):        self.assertRaises(TypeError, A)            def testIsinstance(self):        a = A.Instance()        self.assertTrue(isinstance(a, A))        self.assertFalse(isinstance(a, list))if __name__ == "__main__":    unittest.main()

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.