2009-04-14 5 views
7

파이썬에서 borg를 구현하는 데 문제가 있습니다. 내가 this question에 대한 답을 찾았지만 뭔가 빠뜨린 게 아니라면 저에게는 효과가 없습니다. 코드는 다음과 같습니다.파이썬 보그 패턴 문제

"Hello"를 인쇄하는 것으로 가정합니다.하지만 나를 위해 빈 줄만 인쇄합니다. 왜 이런 생각일까요?

+1

왜 특성에 __ 이름을 사용하고 있습니까? 단 하나의 선도자가 그것을 "비공개"로 만들 것입니다. –

+0

글쎄, 내가 링크 한 다른 질문의 코드를 복사했다. 그러나 어쨌든, 나는 그것이 개인이라고 암시한다고 생각했지만, double _은 사용자가 결정되면 여전히 액세스 할 수 있지만, 실제로는 사적이라는 더 강한 힌트 인 이름 맹 글링을 야기합니다. – chrism1

+2

아니요! 한 줄의 밑줄 문자는 비공개로 만들지 않으며 모듈 수준 변수는 'from 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()의 구현은 조금 이상합니다. 명시 적 getter 및 setter 속성을 사용하는 것이 더 좋을 것입니다. __init__에 코드가 아직 존재하지 않거나 최소한 getter에 존재하지 않을 수도 있다고 처리하는 경우 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 
+0

하! 확실히 명백하게, 그것을 발견 했음에 틀림 없다. 모든 팁을 가져 주셔서 감사합니다. – chrism1

+0

이 Borg 구현은 새로운 스타일의 클래스에서는 작동하지 않는다고 생각했습니다. 내가 놓친 게 있니? – legesh

+0

@legesh 파이썬 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