Несколько лет назад я нашел реализацию шаблона Singleton в Python Duncan Booth:
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
Тот же подход также описан в вопросе "Существует ли простой и элегантный способ определения Singletons в Python?
Я использую Singleton через подкласс: 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)
Я нашел объяснение (от 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 <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)
Gimmel предлагает другое решение : _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
В той же проблеме есть также Menno Smits. Но я не понимаю предлагаемое . Более того, у меня нет множественного наследования в соответствующем коде.
Я не пробовал другой пример в разделе "Существует простой и элегантный способ определения Singletons в Python?", но с первого взгляда он, вероятно, будет иметь та же проблема.
Я использую шаблон Singleton в программе, и я не хочу полностью переписывать его только из-за одного предупреждения. Таким образом, следующие ответы не помогут мне:
- Синглтон ошибается. Не используйте Singleton вообще.
- Используйте Borg вместо этого, он более pythonic.
- Используйте модуль вместо класса.
В заключение я повторю вопрос:
Как адаптировать шаблон Singleton с учетом предупреждения предупреждения с минимальным воздействием на существующий код?
Edit:
Строка 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")