Несколько лет назад я нашел реализацию шаблона 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?"
Я использую синглтон через подкласс:
class Settings(Singleton)
class Debug(Singleton)
Недавно я сделалнекоторые изменения в программе и это предупреждение:
/media/KINGSTON/Sumid/src/miscutil.py:39: DeprecationWarning:
object.__new__() takes no parameters
cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
Я нашел объяснение (по Гвидо) об устаревании __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 <module>
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
Когда я изменю строку на cls._instance = super(Singleton, cls).__new__(cls)
, я получу:
Traceback (most recent call last):
File "sumid.py", line 1174, in <module>
debug = Debug(settings)
TypeError: __new__() takes exactly 1 argument (2 given)
Дай мне предложит другое решение : _instance = type.__new__(cls)
.Для меня это нарушает наследство:
Traceback (most recent call last):
File "sumid.py", line 1168, in <module>
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, когда инициализация дочернего элемента принимает аргумент:
class Child(Singleton):
def __init__(self,param=None):
print(param)
print("Doing another stuff.")
ch = Child("Some stuff")