有很多次问过类似的问题,但我对它有所了解。我在想Singleton或Borg模式可以用来创建一个对象的实例,或者分享它的状态。我有一个(工作)测试示例,它不能像我期望的那样工作。代码不正确,或者我误解了singleton / borg模式的概念。
我使用singleton和borg模式在文件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(或其他)的实例时,它包含值' 42'在module.py
中添加的列表中?我应该用什么模式/机制来实现这个目标?
答案 0 :(得分:2)
您所看到的行为的原因是,在每次执行__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 # []