Как бы реализовал паттерн singleton

Декоратор:

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

Достоинства:

  • Декораторы зачастую более интуитивны, чем множественное наследование.

Недостатки:

  • Хотя объекты, созданные с использованием MyClass(), будут настоящими singleton объектами, сам MyClass является функцией, а не классом, поэтому вы не можете вызывать методы класса из него.
  • Увеличивает сложность тестирования

Base class: 

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

Достоинства:

  • Это настоящий класс.

Недостатки:

  • Множественное наследование усложняет код. __new__ может быть перезаписан во время наследования от второго базового класса?

 Метаклассы:

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

Достоинства:

  • Это настоящий класс
  • Автомагически покрывает наследование
  • Используем метаклассы по их прямому назначению

Недостатки:

  • А они есть?

 Модуль:

Достоинства:

  • Простота

Недостатки:

  • Не инициализируется лениво

 

Oct. 9, 2023, Источник