Python Singleton表现怪异

我想创建一个python单例类,以便在程序打开后代码中的其他任何地方调用该类时,该类的实例完全相同。

我试图找到单例示例,并从链接中找到了一个:https://wikidocs.net/3693

class Singleton(object):

    _instance = None

    def __new__(class_, *args, **kwargs):

        if not isinstance(class_._instance, class_):

            class_._instance = object.__new__(class_, *args, **kwargs)

        return class_._instance

然后像这样测试


class Test(Singleton):

    def __init__(self, name=None):

        print(name)


test1 = Test('a')

期望显示初始化时给出的名称 但这给了我一个错误


TypeError                                 Traceback (most recent call last)

<ipython-input-55-f3383e846037> in <module>()

----> 1 test1 = Test('a')


<ipython-input-33-222ac7a13884> in __new__(class_, *args, **kwargs)

     27     def __new__(class_, *args, **kwargs):

     28         if not isinstance(class_._instance, class_):

---> 29             class_._instance = object.__new__(class_, *args, **kwargs)

     30         return class_._instance


TypeError: object() takes no parameters

但是当我尝试这个时,这个成功了


Test() # with no prarameter

test1 = Test('a') # this prints 'a' without error

我想知道如何解决这个问题。否则,当我启动程序时,我必须在开始时初始化不带参数。


我想获取参数的原因是,当参数在某个时候更改时,我想将更改的信息应用于调用此类的所有位置。


达令说
浏览 89回答 1
1回答

炎炎设计

单例模式在 Python 中毫无意义。几乎总是,你最好使用模块。或者一些工厂功能作为您的主要构造 API,例如 .getLogger如果你真的坚持让你的类表面上成为一个单例(这总是可以被颠覆的),我建议元类方法,因为它回避了覆盖的各种复杂性,尽管元类引入了自己的复杂性。__new__但是为了解决您的问题,这段代码已经过时了,将参数传递给现在将抛出错误,而不是简单地忽略。要完成这项工作,只需不要将任何参数传递给__new__:object.__new__In [1]: class Singleton(object):&nbsp; &nbsp;...:&nbsp; &nbsp; &nbsp;_instance = None&nbsp; &nbsp;...:&nbsp; &nbsp; &nbsp;def __new__(class_, *args, **kwargs):&nbsp; &nbsp;...:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if not isinstance(class_._instance, class_):&nbsp; &nbsp;...:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;class_._instance = object.__new__(class_)&nbsp; &nbsp;...:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return class_._instance&nbsp; &nbsp;...:In [2]: class Test(Singleton):&nbsp; &nbsp;...:&nbsp; &nbsp; &nbsp;def __init__(self, name=None):&nbsp; &nbsp;...:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;print(name)&nbsp; &nbsp;...:&nbsp; &nbsp;...: test1 = Test('a')a注意,每次“实例化”单例时都会调用:__init__In [3]: test2 = Test('b')bIn [4]: test1 is test2Out[4]: True这可能是可取的,也可能是不可取的。但是认真地重新考虑您是否需要单例课程。即使在有意义的语言中,例如Java,它们通常也是一种反模式,并且只是在OOP封装的外观中隐藏可变全局状态的一种方式。这再次使我想到了仅使用模块的原始建议,那么您没有任何借口。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python