2009-04-14 51 views
7

我在執行Python中的borg時遇到了問題。我在this question的答案中找到了一個例子,但它不適用於我,除非我錯過了一些東西。下面的代碼:Python borg模式問題


class Config: 
    """ 
    Borg singleton config object 
    """ 
    __we_are_one = {} 
    __myvalue = "" 

    def __init__(self): 
     #implement the borg pattern (we are one) 
     self.__dict__ = self.__we_are_one 
     self.__myvalue = "" 

    def myvalue(self, value=None): 
     if value: 
      self.__myvalue = value 
     return self.__myvalue 

conf = Config() 
conf.myvalue("Hello") 
conf2 = Config() 
print conf2.myvalue() 

我認爲這是爲了打印「Hello」,但對我來說只是打印一個空行。任何想法,爲什麼這可能是?

+1

你爲什麼使用雙__名稱作爲屬性?一個領先的_將會使其成爲「私人」。 – 2009-04-14 14:55:57

+0

那麼我複製了我鏈接到的其他問題的代碼。但無論如何,我認爲單個_暗示它是私人的,而double _則會導致名稱被破壞,這更強烈地暗示它真的*是私有的,儘管如果用戶被確定仍然可以訪問它。 – chrism1 2009-04-14 15:13:03

回答

13

它看起來像它的工作,而太清楚了:-)

的問題是,在__init__分配self.__myvalue = ""將每一次新的博格是,呃,創造總是揍的myvalue值。你可以看到這一點,如果你添加一些額外的打印語句來測試:

conf = Config() 
conf.myvalue("Hello") 
print conf.myvalue() # prints Hello 
conf2 = Config() 
print conf.myvalue() # prints nothing 
print conf2.myvalue() # prints nothing 

取出self.__myvalue,事情將被罰款。

話雖如此,myvalue()的實施有點奇怪。更好的是,我會說,有明確的使用屬性的getter和setter。如果myvalue還不存在,或者至少要處理它可能不存在於getter中,您還需要__init__中的某些代碼初始化myvalue的值。也許是這樣的:

class Config(object): 
    """ 
    Borg singleton config object 
    """ 
    _we_are_one = {} 

    def __init__(self): 
     #implement the borg pattern (we are one) 
     self.__dict__ = self._we_are_one 

    def set_myvalue(self, val): 
     self._myvalue = val 

    def get_myvalue(self): 
     return getattr(self, '_myvalue', None) 

    myvalue = property(get_myvalue, set_myvalue) 

c = Config() 
print c.myvalue # prints None 
c.myvalue = 5 
print c.myvalue # prints 5 
c2 = Config() 
print c2.myvalue #prints 5 
1

問題似乎是init()將myvalue重置爲空字符串。當我刪除該行時,我會得到預期的輸出。

4

結合去除self.__myvalue = ""new-style Borg和建議,以避免在變量名__,我們得到:

class Config(object): 
    """ 
    Borg singleton config object 
    """ 
    _we_are_one = {} 
    _myvalue = "" 

    def __new__(cls, *p, **k): 
     self = object.__new__(cls, *p, **k) 
     self.__dict__ = cls._we_are_one 
     return self 

    def myvalue(self, value=None): 
     if value: 
      self._myvalue = value 
     return self._myvalue 

if __name__ == '__main__': 
    conf = Config() 
    conf.myvalue("Hello") 
    conf2 = Config() 
    print conf2.myvalue() 
1
class Borg(object): 
    """Demonstrating the Borg-pattern: All the instances of a class already 
    know what one of them learned... Scary, isn't it?""" 

    def __init__(self, name): 
     self.name = name 

    @classmethod 
    def borg_knowledge(cls, who_is_it): 
     if hasattr(cls, "b_knowledge"): 
      return "%s: I already know that the borg pattern is awesome!" % who_is_it 
     else: 
      cls.b_knowledge = True 
      return "%s: Learning about the borg pattern..." % who_is_it 

    def personal_experience(self): 
     if hasattr(self, "p_knowledge"): 
      return "%s: I already know that!" % self.name 
     else: 
      self.p_knowledge = True 
      return "%s: Learning something..." % self.name 


b1 = Borg("b1") 
b2 = Borg("b2") 
print ">> Created b1 and b2, both Borg"; print 

print ">> Usual class behavior. One instance does not know what the other does." 
print b1.personal_experience() 
print b2.personal_experience() 

print 
print ">> Borg have a shared knowledge a.k.a. why classmethods are different!" 
print b1.borg_knowledge(b1.name) 
print b2.borg_knowledge(b2.name) 
0
> The problem appears to be that init() is resetting myvalue to an 
> empty string. When You remove that 
> line ('self.__myvalue = ""') then you will get the expected 
> output. 
0

我嘗試使用實施這一「舊式」以及「新式」,我看不出它們之間的區別。一個人比另一個人有優勢嗎?還是這些基本相同?

class Borg(object): 
    shared_state = {'a_value': True} 
    def __init__(self): 
     self.__dict__ = self.shared_state 


class NewBorg(object): 
    shared_state = {'a_value': True} 

    def __new__(cls, *p, **k): 
     self = object.__new__(cls, *p, **k) 
     self.__dict__ = cls.shared_state 
     return self 


borg_a = Borg() 
borg_b = Borg() 

print id(borg_a), '!=', id(borg_b) 
assert borg_a.shared_state == borg_b.shared_state 
borg_a.shared_state['a_value'] = False 
assert borg_a.shared_state == borg_b.shared_state 

new_borg_a = NewBorg() 
new_borg_b = NewBorg() 

print id(new_borg_a), '!=', id(new_borg_b) 
assert new_borg_a.shared_state == new_borg_b.shared_state 
new_borg_a.shared_state['a_value'] = False 
assert new_borg_a.shared_state == new_borg_b.shared_state