几年前,我在 Python 中发现了 Singleton 模式的实现:邓肯·布斯 http://web.archive.org/web/20090619190842/http://www.suttoncourtenay.org.uk/duncan/accu/pythonpatterns.html:
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 中定义单例? https://stackoverflow.com/questions/31875/is-there-a-simple-elegant-way-to-define-singletons-in-python/1810391#1810391"
我通过子类使用单例:
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)
I found 解释 http://mail.python.org/pipermail/python-dev/2008-February/076854.html(圭多)关于__new__
deprecation 表示根本不使用这些参数。传递不需要的参数可能是错误的症状。
所以我决定清除参数:
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)
吉梅尔建议另一个solution https://stackoverflow.com/questions/1590477/python-deprecation-warnings-with-monostate-new-can-someone-explain-why/1590586#1590586: _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
相同problem http://freshfoo.com/blog/object__init__takes_no_parameters还有门诺·史密茨(Menno Smits)。但我不明白solution http://www.artima.com/weblogs/viewpost.jsp?thread=281127建议。而且我在相关代码中没有多重继承。
我没有尝试另一个example https://stackoverflow.com/questions/31875/is-there-a-simple-elegant-way-to-define-singletons-in-python/33201#33201在“Python中有没有一种简单、优雅的方法来定义单例?”中,但乍一看很可能会遇到同样的问题。
我在程序中使用单例模式,并且不想仅仅因为一个警告就完全重写它。因此以下答案对我没有帮助:
- 辛格尔顿错了。根本不要使用单例。
- 使用 Borg 代替,它更Pythonic。
- 使用模块而不是类。
最后,我将重复这个问题:
How to 适应单例模式考虑到弃用警告与影响最小现有代码?
Edit:
Line cls._instance = object.__new__(cls)
当 Child 的 init 接受参数时引发 TypeError:
class Child(Singleton):
def __init__(self,param=None):
print(param)
print("Doing another stuff.")
ch = Child("Some stuff")