This question is not for the discussion of whether or not the singleton design pattern is desirable, is an anti-pattern, or for any religious wars, but to discuss how this pattern is best implemented in Python in such a way that is most pythonic. 這個問題不是爲了討論是否須要單例設計模式 ,是不是反模式,仍是針對任何宗教戰爭,而是要討論如何以最pythonic的方式在Python中最好地實現此模式。 In this instance I define 'most pythonic' to mean that it follows the 'principle of least astonishment' . 在這種狀況下,我定義「最pythonic」來表示它遵循「最少驚訝的原理」 。 python
I have multiple classes which would become singletons (my use-case is for a logger, but this is not important). 我有多個將成爲單例的類(個人用例用於記錄器,但這並不重要)。 I do not wish to clutter several classes with added gumph when I can simply inherit or decorate. 當我能夠簡單地繼承或修飾時,我不但願增長gumph來使幾個類雜亂無章。 設計模式
Best methods: 最佳方法: 函數
def singleton(class_): instances = {} def getinstance(*args, **kwargs): if class_ not in instances: instances[class_] = class_(*args, **kwargs) return instances[class_] return getinstance @singleton class MyClass(BaseClass): pass
Pros 優勢 ui
Cons 缺點 this
m = MyClass(); n = MyClass(); o = type(n)();
一樣對於m = MyClass(); n = MyClass(); o = type(n)();
m = MyClass(); n = MyClass(); o = type(n)();
then m == n && m != o && n != o
而後m == n && m != o && n != o
class Singleton(object): _instance = None def __new__(class_, *args, **kwargs): if not isinstance(class_._instance, class_): class_._instance = object.__new__(class_, *args, **kwargs) return class_._instance class MyClass(Singleton, BaseClass): pass
Pros 優勢 spa
Cons 缺點 .net
__new__
could be overwritten during inheritance from a second base class? __new__
是否能夠在從第二個基類繼承時被覆蓋? One has to think more than is necessary. 人們必須思考的超出了必要。 class Singleton(type): _instances = {} def __call__(cls, *args, **kwargs): if cls not in cls._instances: cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs) return cls._instances[cls] #Python2 class MyClass(BaseClass): __metaclass__ = Singleton #Python3 class MyClass(BaseClass, metaclass=Singleton): pass
Pros 優勢 設計
__metaclass__
for its proper purpose (and made me aware of it) 將__metaclass__
用於其適當的目的(並使我意識到這一點) Cons 缺點 code
def singleton(class_): class class_w(class_): _instance = None def __new__(class_, *args, **kwargs): if class_w._instance is None: class_w._instance = super(class_w, class_).__new__(class_, *args, **kwargs) class_w._instance._sealed = False return class_w._instance def __init__(self, *args, **kwargs): if self._sealed: return super(class_w, self).__init__(*args, **kwargs) self._sealed = True class_w.__name__ = class_.__name__ return class_w @singleton class MyClass(BaseClass): pass
Pros 優勢 對象
Cons 缺點
_sealed
attribute _sealed
屬性的意義是什麼 super()
because they will recurse. 沒法使用super()
在基類上調用相同名稱的方法,由於它們會遞歸。 This means you can't customize __new__
and can't subclass a class that needs you to call up to __init__
. 這意味着您不能自定義__new__
,也不能將須要調用__init__
類做爲子類。 a module file singleton.py
一個模塊文件singleton.py
Pros 優勢
Cons 缺點