方法一:使用裝飾器
裝飾器維護一個字典物件instances,快取了所有單例類,只要單例不存在則建立,已經存在直接返回該例項物件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
def singleton(cls): instances = {} def wrapper(*args, **kwargs): if cls not in instances: instances[cls] = cls(*args, **kwargs) return instances[cls] return wrapper @singleton class Foo(object): pass foo1 = Foo() foo2 = Foo() print foo1 is foo2 |
方法二:使用基類
__new__是真正建立例項物件的方法,所以重寫基類的__new__方法,以此來保證建立物件的時候只生成一個例項
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
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 class Foo(Singleton): pass foo1 = Foo() foo2 = Foo() print foo1 is foo2 # True |
方法三:使用元類
元類(參考:深刻理解Python中的元類)是用於建立類物件的類,類物件建立例項物件時一定會呼叫__call__
方法,因此在呼叫__call__
時候保證始終只建立一個例項即可,type
是python中的一個元類。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
class Singleton(type): def __call__(cls, *args, **kwargs): if not hasattr(cls, '_instance'): cls._instance = super(Singleton, cls).__call__(*args, **kwargs) return cls._instance class Foo(object): __metaclass__ = Singleton foo1 = Foo() foo2 = Foo() print foo1 is foo2 # True |