Код: Выделить всё
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
< /code>
pros < /p>
[list]
[*] Декораторы являются аддитивными, которые часто более интуитивны, чем множественное наследство. MyClass
Код: Выделить всё
x = MyClass();
y = MyClass();
t = type(n)();
< /code>
< /li>
< /ul>
Тогда x == y < /code> но x! = t && y!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
< /code>
pros < /p>
Это настоящий класс < /li>
< /ul>
минусы < /p>
Множественное наследство - Eugh! __new __
< /ul>
Метод 3: Metaclass < /h2>
Код: Выделить всё
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
It's a true class
[*]Auto-magically covers inheritance
[*]Uses __metaclass__ for its proper purpose (and made me aware of it)
[/list]
Cons
- Есть ли есть?
Код: Выделить всё
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 < /code> pros < /p> Это настоящий класс < /li> Автомагически покрывает наследие < /li> < /ul> минусы < /p> не является каждым новым классом? Здесь мы создаем два класса для каждого класса, который мы хотим сделать синглтоном. Хотя в моем случае это нормально, я беспокоюсь, что это может не масштабироваться. Конечно, существует вопрос дебатов относительно того, слишком ли это легко масштабировать этот шаблон ... [*] Какой смысл атрибута
- не может назвать методы одного и того же имени, используя Super () . Это означает, что вы не можете настроить __new __ и не можете подключить класс, который нуждается в том, чтобы вы могли вызвать до __init __ .
module file singleton.py>
module file singleton. /> pros < /p>
Проще является анти-паттерном или для любых религиозных войн, но для обсуждения того, как этот шаблон лучше всего реализуется в Python таким образом, что является наиболее питоническим. В этом случае я определяю «самый питоник», чтобы означать, что он следует «принципу наименьшего удивления».
Подробнее здесь: https://stackoverflow.com/questions/676 ... -in-python