2009-04-14 13 views
7

मुझे अजगर में एक बोर्ग को लागू करने में समस्याएं आ रही हैं। मुझे this question के उत्तर में एक उदाहरण मिला लेकिन यह मेरे लिए काम नहीं कर रहा है, जब तक कि मुझे कुछ याद नहीं आ रहा है। यहां कोड है:पायथन बोर्ग पैटर्न समस्या


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() 

मुझे लगता है कि यह "हैलो" प्रिंट करने के लिए है, लेकिन मेरे लिए यह सिर्फ एक खाली रेखा प्रिंट करता है। कोई विचार यह क्यों हो सकता है?

+1

आप अपने गुणों के लिए डबल __ नाम क्यों उपयोग कर रहे हैं? एक अग्रणी अग्रणी _ इसे "निजी" बनाने के लिए करेगा। –

+0

वैसे मैंने कोड को दूसरे प्रश्न से कॉपी किया है जिसे मैंने लिंक किया था। लेकिन वैसे भी, मैंने सोचा कि एक सिंगल _ संकेत है कि यह निजी है, जबकि एक डबल _ नाम का नाम बदलता है जो एक मजबूत संकेत है कि यह वास्तव में निजी है, हालांकि उपयोगकर्ता को निर्धारित होने पर इसे अभी भी एक्सेस किया जा सकता है। – chrism1

+2

नहीं! एकल अग्रणी अंडरस्कोर उन्हें निजी नहीं बनाएगा, केवल इसे बनायेगा ताकि मॉड्यूल स्तर चर 'foo import * से' आयात नहीं किए जा सकें अन्यथा, इसका गोपनीयता पर 'संकेत' के अलावा कोई प्रभाव नहीं पड़ता है। –

उत्तर

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() का कार्यान्वयन थोड़ा अजीब है। बेहतर, मैं कहूंगा, गुणों का उपयोग कर स्पष्ट गेटर्स और सेटर्स रखना। myvalue के मान को प्रारंभ करने के लिए आपको __init__ में कुछ कोड भी चाहिए, यदि यह अभी तक मौजूद नहीं है, या कम से कम यह संभालने के लिए कि यह गेटटर में मौजूद नहीं है। शायद की तरह कुछ:

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 
+0

हा है! वास्तव में स्पष्ट रूप से स्पष्ट, इसे देखा जाना चाहिए था। सभी सुझावों के लिए धन्यवाद। – chrism1

+0

मैंने सोचा कि यह बोर्ग कार्यान्वयन नई शैली के वर्गों के साथ काम नहीं करता है। क्या मैं कुछ भूल रहा हूँ? – legesh

+0

@legesh यह Python 2.6 में ठीक काम करता प्रतीत होता है। शायद मुझे कुछ याद आ रहा है ... आपको कौन सी जानकारी या अनुभव आपको नई शैली के वर्गों के साथ रोक देता है? –

1

समस्या यह प्रतीत होती है कि init() एक खाली स्ट्रिंग पर myvalue को रीसेट कर रहा है। जब मैं उस रेखा को हटा देता हूं तो मुझे अपेक्षित आउटपुट मिलता है।

4

new-style Borg और सुझावों के साथ self.__myvalue = "" को हटाने का मेल चर नाम में __ से बचने के लिए, हम पाते हैं:

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 
संबंधित मुद्दे