2013-03-21 50 views
1

類似的問題已經被問過很多次了,但是我有理解它的問題。我在想,Singleton或Borg模式可以用來創建一個對象的一個​​實例,或者共享它的狀態。我有一個(工作)測試示例,它不能像我期望的那樣工作。代碼不正確,或者我誤解了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() 

One s在後兩個類中應該用MySingleton代替MyBorg來使用Singleton而不是borg。

現在,當我運行主代碼時,我清楚地看到modules.py被首先調用,將一個值添加到列表中。之後,Singleton/Borg模式也在主代碼中實例化,並且(另一個)值被添加。我期望在列表中有兩個值(42和4711),而我只有列表中的後一個值。

可能出現module.py中的實例超出範圍,因此module.py中的任何操作都已被刪除。但是我需要的是有些東西的目標是包含相同的內容,無論我在哪裏使用它。

我該如何做到這一點?我怎樣才能確保,當我創建對象MyBorg(或其他)的實例時,它在列表中包含值'42',如在module.py中添加的那樣?我應該使用什麼模式/機制來實現這個目標?

回答

2

您看到的行爲的原因是,在這兩種情況下,您每次都會調用__init__instance = WhateverClass()

請注意,您正在通過相同實例左右。但是,該實例在__init__中清除了_list屬性。

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 # [] 
+0

嗯好點。但是在哪裏設置它爲空列表?我需要找出什麼時候創建第一個實例?或者在Singleton的'__new__'方法中硬編碼? – Alex 2013-03-21 15:44:58

+0

最好的做法是調整borg模式並寫下'__shared_state = {'_list':[]}'而不是?即在共享狀態字典中初始化我需要的內容? – Alex 2013-03-21 15:48:00

+2

我一般不認爲單身人士是件好事......在某些情況下,模塊可以做出體面的單身人士(儘管你無法將其細分)。你可以做的另一件事是向你的Singleton API添加一個'initialized'變量。你可以在'__new__'中設置'class _._ intstance.initialized = False'。然後,子類中的__init__負責將self.initialized設置爲True,如果self.initialized設置爲True,則不執行。 – mgilson 2013-03-21 15:50:42

相關問題