Есть ли простой, элегантный способ определения синглетонов? [Дубликат]

https://docs.oracle.com/javase/8/docs/platform/serialization/spec/serialTOC.html

Сериализация по умолчанию несколько многословна и предполагает максимально возможный сценарий использования сериализованного объекта, и, соответственно, формат по умолчанию (Serializable) аннотирует результирующий поток с информацией о классе сериализованного объекта.

Внешняя подача дает разработчику полный поток объектов точные метаданные класса (если таковые имеются) за минимально необходимой идентификацией класса (например, его имя). Это явно желательно в определенных ситуациях, таких как закрытые среды, в которых сопоставляются производитель потока объектов и его потребителя (который подтверждает объект из потока), а дополнительные метаданные о классе не имеют никакой цели и ухудшают производительность.

Дополнительно (как указано Uri) экстернализация также обеспечивает полный контроль над кодированием данных в потоке, соответствующем типам Java. Для (надуманного) примера вы можете записать логическое значение true, как «Y», а false - «N». Вы можете сделать это вовне.

416
задан martineau 7 February 2017 в 19:44
поделиться

12 ответов

Я действительно не вижу потребность, поскольку модуль с функциями (и не класс) служил бы хорошо в качестве одиночного элемента. Все его переменные были бы связаны с модулем, который нельзя было инстанцировать неоднократно так или иначе.

, Если Вы действительно хотите использовать класс, нет никакого способа создать частные классы или частных конструкторов в Python, таким образом, Вы не можете защитить от нескольких инстанцирований, кроме только с помощью соглашения, используемого из Вашего API. Я все еще просто поместил бы методы в модуль и рассмотрел бы модуль как одиночный элемент.

338
ответ дан Peter Mortensen 7 February 2017 в 19:44
поделиться

Шаблон "одиночка" реализован с любезностью Python ActiveState.

похоже, что прием должен поместить класс, это, как предполагается, только имеет один экземпляр в другом классе.

3
ответ дан Mark Biek 7 February 2017 в 19:44
поделиться

Существуют также некоторые интересные статьи о блоге Google Testing, обсуждая, почему одиночный элемент/может быть плохим и является антишаблоном:

9
ответ дан David Kemp 7 February 2017 в 19:44
поделиться

Одно время, которое я записал одиночному элементу в Python, я использовал класс, где все функции членства имели classmethod декоратора.

class foo:
  x = 1

  @classmethod
  def increment(cls, y = 1):
    cls.x += y
14
ответ дан David Locke 7 February 2017 в 19:44
поделиться

Быть относительно в новинку для Python, я не уверен, какова наиболее распространенная идиома, но самая простая вещь, о которой я могу думать, просто использует модуль вместо класса. Что было бы методами экземпляра для Вашего класса, становятся просто функциями в модуле, и любые данные просто становятся переменными в модуле вместо членов класса. Я подозреваю, что это - подход pythonic к решению типа проблемы, для которой люди используют одиночные элементы.

, Если Вы действительно хотите singleton-класс, существует разумная реализация, описанная на первый хит на Google для "одиночного элемента Python", конкретно:

class Singleton:
    __single = None
    def __init__( self ):
        if Singleton.__single:
            raise Singleton.__single
        Singleton.__single = self

, Который, кажется, добивается цели.

3
ответ дан Peter Mortensen 7 February 2017 в 19:44
поделиться

Подход модуля работает хорошо. Если мне абсолютно нужен одиночный элемент, я предпочитаю подход Метакласса.

class Singleton(type):
    def __init__(cls, name, bases, dict):
        super(Singleton, cls).__init__(name, bases, dict)
        cls.instance = None 

    def __call__(cls,*args,**kw):
        if cls.instance is None:
            cls.instance = super(Singleton, cls).__call__(*args, **kw)
        return cls.instance

class MyClass(object):
    __metaclass__ = Singleton
79
ответ дан unutbu 7 February 2017 в 19:44
поделиться

Немного отличающийся подход для реализации одиночного элемента в Python borg шаблон Alex Martelli (сотрудник Google и гений Python).

class Borg:
    __shared_state = {}
    def __init__(self):
        self.__dict__ = self.__shared_state

Так вместо того, чтобы вынудить все экземпляры иметь те же идентификационные данные, они совместно используют состояние.

108
ответ дан Peter Mortensen 7 February 2017 в 19:44
поделиться

Вот пример от Python IAQ Peter Norvig, Как я делаю Шаблон "одиночка" в Python? (Необходимо использовать функцию поиска браузера для нахождения этого вопроса, нет никакой прямой ссылки, извините)

, Также у Bruce Eckel есть другой пример в его книге , Думающей в Python (снова нет никакой прямой ссылки на код)

7
ответ дан Serge 7 February 2017 в 19:44
поделиться

Вы можете переопределить метод __ new __ следующим образом :

class Singleton(object):
    _instance = None
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(Singleton, cls).__new__(
                                cls, *args, **kwargs)
        return cls._instance


if __name__ == '__main__':
    s1 = Singleton()
    s2 = Singleton()
    if (id(s1) == id(s2)):
        print "Same"
    else:
        print "Different"
183
ответ дан 22 November 2019 в 23:18
поделиться

Я очень не уверен в этом, но в моем проекте используются «синглтоны соглашения» (не принудительные синглтоны), то есть, если у меня есть класс с именем DataController , я определите это в том же модуле:

_data_controller = None
def GetDataController():
    global _data_controller
    if _data_controller is None:
        _data_controller = DataController()
    return _data_controller

Это не элегантно, так как это полные шесть строк. Но все мои синглтоны используют этот шаблон, и он, по крайней мере, очень явный (питонический).

20
ответ дан 22 November 2019 в 23:18
поделиться
class Singleton(object[,...]):

    staticVar1 = None
    staticVar2 = None

    def __init__(self):
        if self.__class__.staticVar1==None :
            # create class instance variable for instantiation of class
            # assign class instance variable values to class static variables
        else:
            # assign class static variable values to class instance variables
2
ответ дан 22 November 2019 в 23:18
поделиться

См. эту реализацию из PEP318, реализуя шаблон синглтона с декоратором:

def singleton(cls):
    instances = {}
    def getinstance():
        if cls not in instances:
            instances[cls] = cls()
        return instances[cls]
    return getinstance

@singleton
class MyClass:
    ...
43
ответ дан 22 November 2019 в 23:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: