为了账号安全,请及时绑定邮箱和手机立即绑定

Python Singleton表现怪异

Python Singleton表现怪异

达令说 2023-10-11 21:11:18
我想创建一个python单例类,以便在程序打开后代码中的其他任何地方调用该类时,该类的实例完全相同。我试图找到单例示例,并从链接中找到了一个:https://wikidocs.net/3693class 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_._instanceTypeError: object() takes no parameters但是当我尝试这个时,这个成功了Test() # with no prarametertest1 = Test('a') # this prints 'a' without error我想知道如何解决这个问题。否则,当我启动程序时,我必须在开始时初始化不带参数。我想获取参数的原因是,当参数在某个时候更改时,我想将更改的信息应用于调用此类的所有位置。
查看完整描述

1 回答

?
炎炎设计

TA贡献1808条经验 获得超4个赞

单例模式在 Python 中毫无意义。几乎总是,你最好使用模块。或者一些工厂功能作为您的主要构造 API,例如 .getLogger

如果你真的坚持让你的类表面上成为一个单例(这总是可以被颠覆的),我建议元类方法,因为它回避了覆盖的各种复杂性,尽管元引入了自己的复杂性。__new__

但是为了解决您的问题,这段代码已经过时了,将参数传递给现在将抛出错误,而不是简单地忽略。要完成这项工作,只需不要将任何参数传递给__new__object.__new__

In [1]: class Singleton(object):

   ...:     _instance = None

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

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

   ...:             class_._instance = object.__new__(class_)

   ...:         return class_._instance

   ...:


In [2]: class Test(Singleton):

   ...:     def __init__(self, name=None):

   ...:         print(name)

   ...:

   ...: test1 = Test('a')

a

注意,每次“实例化”单例时都会调用:__init__


In [3]: test2 = Test('b')

b


In [4]: test1 is test2

Out[4]: True

这可能是可取的,也可能是不可取的。


但是认真地重新考虑您是否需要单例课程。即使在有意义的语言中,例如Java,它们通常也是一种反模式,并且只是在OOP封装的外观中隐藏可变全局状态的一种方式。这再次使我想到了仅使用模块的原始建议,那么您没有任何借口。


查看完整回答
反对 回复 2023-10-11
  • 1 回答
  • 0 关注
  • 49 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信