Python单例模式

时间:2010-06-14 14:11:01

标签: python singleton

有人可以告诉我为什么这是不正确的单身模式:

class preSingleton(object):
    def __call__(self):
        return self

singleton = preSingleton()

# singleton is actually the singleton

a = singleton()
b = singleton()

print a==b  

a.var_in_a = 100
b.var_in_b = 'hello'

print a.var_in_b
print b.var_in_a

修改:上面的代码打印出来:

True
hello
100

非常感谢

第二部分

也许这更好?

class Singleton(object):
    def __new__(cls):
        return cls

a = Singleton()
b = Singleton()

print a == b

a.var_in_a = 100
b.var_in_b = 'hello'

print a.var_in_b
print b.var_in_a

修改:上面的代码打印出来:

True
hello
100

再次感谢。

6 个答案:

答案 0 :(得分:10)

单身人士在Python中实际上非常简单。诀窍是让模块为你做封装而不是上课。

  • 模块只会初始化一次
  • 直到第一次导入模块时才会初始化模块
  • 任何重新导入模块的尝试都将返回指向现有导入的指针

如果你想假装模块是一个类的实例,你可以执行以下操作

import some_module
class SomeClass(object):
    def __init__(self):
        self.singleton = some_module

答案 1 :(得分:3)

因为这不是单身人士。单身必须是单身,你的对象不是。

>>> class preSingleton(object):
...     def __call__(self):
...         return self
...
>>> singleton = preSingleton()
>>> singleton2 = preSingleton()
>>> singleton
<__main__.preSingleton object at 0x00C6D410>
>>> singleton2
<__main__.preSingleton object at 0x00C6D290>

答案 2 :(得分:2)

这实际上是博格模式。共享状态的多个对象。

这并不是说它有什么问题,对于大多数(如果不是全部)用例,它的功能相当于单身,但是因为你问过......

编辑:当然因为它们是Borg对象,所以每个实例都占用了更多的内存,所以如果你创建了大量内存,这将对资源的使用产生影响。

答案 3 :(得分:2)

这是一个作为装饰者实现的性感小单身人士:

def singleton(cls):
    """Decorate a class with @singleton when There Can Be Only One."""
    instance = cls()
    instance.__call__ = lambda: instance
    return instance

像这样使用:

@singleton
class MySingleton:
    def spam(self):
        print id(self)

在类定义之外,MySingleton实际上将引用存在的类的唯一实例,并且您将没有创建任何新实例的机制。调用MySingleton()只会返回完全相同的实例。例如:

>>> MySingleton
<__main__.MySingleton instance at 0x7f474b9265a8>
>>> MySingleton()
<__main__.MySingleton instance at 0x7f474b9265a8>
>>> MySingleton() is MySingleton
True
>>> MySingleton.spam()
139944187291048
>>> MySingleton().spam()
139944187291048

答案 4 :(得分:1)

我没有看到问题(如果它像鸭子一样走路,像鸭子那样嘎嘎叫......)。看起来像个单身人士。

它与Java单例(例如)的工作方式不同,因为Python使用相同的语法来调用函数来创建对象的新实例。所以singleton()实际上是调用单个对象,它返回自己。

答案 5 :(得分:0)

您可以在课堂上执行此操作:

>>> class preSingleton(object):
...     def __call__(self):
...         return self
...
>>> x = preSingleton()
>>> y = preSingleton()
>>> x == y
False

因此,可以创建多个类的实例,并且它违反了Singleton模式。