类似的问题已经问过很多次了,但是我在理解它上有困难。我当时认为Singleton或Borg模式只能用于创建一个对象实例或共享其状态。我有一个(工作中的)测试示例,它不能按我预期的那样工作。代码不正确,或者我误解了单例/博格模式的概念。

我使用了singletonborg模式在文件borg.py中创建以下代码:

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 MySingleton(Singleton):

    def __init__(self):
        self._list = []

    def add(self,x):
        self._list.append(x)

    def get(self):
        return self._list

class MyBorg(object):
    __shared_state = {}
    def __init__(self):
        self.__dict__ = self.__shared_state
        # and whatever else you want in your class -- that's all!
        self._list = []

    def add(self,x):
        self._list.append(x)

    def get(self):
        return self._list


然后是文件module.py

from borg import MyBorg
myborg = MyBorg()
myborg.add(42)
print "just added something"


最后是主要代码:

from borg import MyBorg
import module
myborg = MyBorg()
myborg.add(4711)
print myborg.get()


在后两个类中,应使用MyBorg替换MySingleton以使用Singleton而不是borg。

现在,当我运行主代码时,我可以清楚地看到首先调用modules.py,并将一个值添加到列表中。此后,还在主代码中实例化Singleton / Borg模式,并添加了(另一个)值。我希望列表中有两个值(42和4711),而列表中只有后者。

module.py中的实例可能超出范围,因此module.py中的所有操作都已删除。但是我需要做的就是让一个对象包含相同的内容,无论我在哪里使用它。

我该如何实现?我如何确定创建对象MyBorg(或其他任何对象)的实例时,它在列表中包含module.py中添加的值“ 42”?我应该使用什么模式/机制来实现这一目标?

最佳答案

您看到的行为的原因是,在两种情况下,每次执行__init__都会调用instance = WhateverClass()

请注意,您正在传递相同的实例。但是,该实例正在清除_list中的__init__属性。

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 Foo(Singleton):
    def __init__(self):
        self.data = []
    pass

a = Foo()
a.data.append('Never see this')
b = Foo()
print a is b  #True
print a.data  # []

10-08 13:10