【问题标题】:Singleton Implementation using Function使用函数的单例实现
【发布时间】:2023-03-18 02:29:01
【问题描述】:

我在这个 SO question 中了解了创建单例函数的多种方法。

我想出了另一种方法

def my_singleton():

    if not my_singleton.instance:
        class MyClass:
            pass

        my_singleton.instance = MyClass()

    return my_singleton.instance

my_singleton.instance = None

与上一个 SO 问题中提到的其他方法相比,这种方法有什么问题?是否有与实例的内存/GC/线程安全/生命周期相关的任何含义。我问这个是因为其他方法对于初学者来说看起来相当复杂(元类、装饰器、基类、装饰器返回类)

【问题讨论】:

  • 我不确定函数方法,但可以肯定您的代码无法生成AttributeError: 'function' object has no attribute 'instance'
  • 为什么需要单例?只需将对象传递到需要它的地方。 Explicit is better than implicit.
  • 您需要为my_singleton.instance设置一个初始值。除此之外,您只是手动缓存一个值。没有错。
  • 谢谢我错过了最后一行。修改了代码。

标签: python optimization design-patterns singleton


【解决方案1】:

除了实例属性的问题 (AttributeError: 'function' object has no attribute 'instance') 之外,这种方法还有另一个问题。使用my_singleton 创建“几乎单例”对象后,您可以简单地从该对象获取类并创建该类的 对象。

x = my_singleton()
y = my_singleton()
x == y
Out[50]: True

z = x.__class__()
type(z) == type(x)
Out[52]: True

z == x
Out[53]: False

顺便说一句。以下是我修复my_singleton() 函数的方法(不是为了引发属性错误,但它仍然不是真正的单例):

def my_singleton():
    try:
        return my_singleton.instance
    except AttributeError:
        class MyClass:
            pass
        my_singleton.instance = MyClass()
        return my_singleton.instance

【讨论】:

  • 啊,谢谢。它与装饰器方法存在相同的问题,并且不会创建纯单例对象。尽管我想不出程序员将使用这种方法来创建实例(有意)的用例。对内存/GC/线程安全/实例生命周期有什么影响吗?
  • 您可以在类级别通过 MyClass.inst = None 堵住这个漏洞,并在 _init_ 中将 self 分配给它并引发异常如果它已经被分配了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-04-15
  • 2018-01-21
  • 1970-01-01
  • 2013-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多