#!/usr/bin/python
#coding: UTF-8
"""
@author: CaiKnife
Singleton
"""
from functools import wraps
# 使用__new__方法構造單例類
class Singleton(object):
def __new__(cls, *args, **kwargs):
if not hasattr(cls, '_instance'):
cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
return cls._instance
print Singleton()
print Singleton()
# 使用單例裝飾器構造單例類
def singleton(cls):
instances = {}
@wraps(cls)
def wrapper(*args, **kwargs):
if cls not in instances:
instances[cls] = cls(*args, **kwargs)
return instances[cls]
return wrapper
@singleton
class MyClass(object):
pass
print MyClass()
print MyClass()
# 使用getInstance方法構造單例對象,非線程安全
class MySingleton(object):
@classmethod
def getInstance(cls):
if not hasattr(cls, '_instance'):
cls._instance = cls()
return cls._instance
print MySingleton.getInstance()
print MySingleton.getInstance()
輸出結果:
<__main__.Singleton object at 0x00BBFBD0>
<__main__.Singleton object at 0x00BBFBD0>
<__main__.MyClass object at 0x00BBFC30>
<__main__.MyClass object at 0x00BBFC30>
<__main__.MySingleton object at 0x00BBFC90>
<__main__.MySingleton object at 0x00BBFC90>
測試代碼:
import __init__, unittest, threading
from singleton import Singleton, MyClass, MySingleton
class TestSingleton(unittest.TestCase):
def setUp(self):
self.singleton_instances = [Singleton() for x in range(100)]
self.my_class_instances = [MyClass() for x in range(100)]
self.my_singleton_instances = [MySingleton.getInstance() for x in range(100)]
def tearDown(self):
del self.singleton_instances, self.my_class_instances, self.my_singleton_instances
def test_singleton(self):
for x in self.singleton_instances:
self.assertIs(x, Singleton())
def test_my_class(self):
for x in self.my_class_instances:
self.assertIs(x, MyClass())
def test_my_singleton(self):
for x in self.my_singleton_instances:
self.assertIs(x, MySingleton.getInstance())
if __name__ == "__main__":
unittest.main()