Как адаптировать шаблон Singleton? (Предупреждение об устаревании)

Немного лет назад я нашел реализацию паттерна Singleton в Python от Дункана Бута :

class Singleton(object):
    """
    Singleton class by Duncan Booth.
    Multiple object variables refers to the same object.
    http://web.archive.org/web/20090619190842/http://www.suttoncourtenay.org.uk/duncan/accu/pythonpatterns.html#singleton-and-the-borg
    """
    _instance = None

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

Тот же подход также описан в вопросе « Есть ли простой и элегантный способ определения синглтонов в Python? «

Я использую Singleton через подкласс:
Настройки класса (Singleton)
Класс Debug (Singleton)

Недавно я внес некоторые изменения в программу и получил это предупреждение:

/media/KINGSTON/Sumid/src/miscutil.py:39: DeprecationWarning: 
object.__new__() takes no parameters
cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)

Я нашел объяснение (от Guido) об устаревании __ new __ , в котором говорится, что параметры вообще не используются. Передача ненужного аргумента может быть признаком ошибки.

Поэтому я решил очистить параметры:

class Singleton(object):
_instance = None

def __new__(cls):
    if not cls._instance:
        cls._instance = super(Singleton, cls).__new__()
    return cls._instance

Что привело к следующему исключению:

Traceback (most recent call last):
 File "sumid.py", line 1168, in 
  settings = Settings()
 File "/media/KINGSTON/Sumid/src/miscutil.py", line 45, in __new__
  cls._instance = super(Singleton, cls).__new__()
 TypeError: object.__new__(): not enough arguments

Когда я изменил строку на [11153 791] cls._instance = super (Singleton, cls) .__ new __ (cls) , я получу:

Traceback (most recent call last):
  File "sumid.py", line 1174, in 
    debug = Debug(settings)
TypeError: __new__() takes exactly 1 argument (2 given)

Gimmel предлагает другое решение : _instance = type .__ new __ (cls ) . Для меня это нарушает наследование:

Traceback (most recent call last):
  File "sumid.py", line 1168, in 
    settings = Settings()
  File "/media/KINGSTON/Sumid/src/miscutil.py", line 40, in __new__
    _instance = type.__new__(cls)
TypeError: type.__new__(Settings): Settings is not a subtype of type

Та же самая проблема имеет и Менно Смитс.Но я не понимаю предложенного решения . Более того, у меня нет множественного наследования в соответствующем коде.

Я не пробовал другой пример в «Есть ли простой и элегантный способ определения синглтонов в Python?», Но на первый взгляд, вероятно, будет та же проблема.

Я использую в программе шаблон Singleton и не хочу полностью его переписывать только из-за одного предупреждения. Таким образом, следующие ответы мне не помогут:

  • Синглтон ошибочен. Не используйте синглтон вообще.
  • Используйте вместо него борг, он более питонический.
  • Используйте модуль вместо класса.

В заключение повторю вопрос:
Как адаптировать шаблон Singleton с учетом предупреждения об устаревании с минимальным влиянием на существующий код?

Изменить: Строка cls._instance = object .__ new __ (cls) вызывает ошибку TypeError, когда дочерний init принимает аргумент:

class Child(Singleton):
    def __init__(self,param=None):
        print(param)
        print("Doing another stuff.")

ch = Child("Some stuff") 

15
задан Community 23 May 2017 в 11:53
поделиться