파이썬에서 borg를 구현하는 데 문제가 있습니다. 내가 this question에 대한 답을 찾았지만 뭔가 빠뜨린 게 아니라면 저에게는 효과가 없습니다. 코드는 다음과 같습니다.파이썬 보그 패턴 문제
"Hello"를 인쇄하는 것으로 가정합니다.하지만 나를 위해 빈 줄만 인쇄합니다. 왜 이런 생각일까요?
파이썬에서 borg를 구현하는 데 문제가 있습니다. 내가 this question에 대한 답을 찾았지만 뭔가 빠뜨린 게 아니라면 저에게는 효과가 없습니다. 코드는 다음과 같습니다.파이썬 보그 패턴 문제
"Hello"를 인쇄하는 것으로 가정합니다.하지만 나를 위해 빈 줄만 인쇄합니다. 왜 이런 생각일까요?
는 __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
문제는 init()이 myvalue를 빈 문자열로 재설정하는 것 같습니다. 내가 그 라인을 제거하면 나는 예상되는 출력을 얻는다. 이
문제 :-) 오히려 너무 잘 일하고있어 마치
가 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()
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)
> 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.
내가 사용이 구현 노력 "구식"뿐만 아니라 "새로운 스타일"도 있고 나는 그들 사이의 차이점을 볼 수 없습니다. 하나가 다른 것에 이점이 있습니까? 아니면 이것들은 기본적으로 동일합니까?
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
왜 특성에 __ 이름을 사용하고 있습니까? 단 하나의 선도자가 그것을 "비공개"로 만들 것입니다. –
글쎄, 내가 링크 한 다른 질문의 코드를 복사했다. 그러나 어쨌든, 나는 그것이 개인이라고 암시한다고 생각했지만, double _은 사용자가 결정되면 여전히 액세스 할 수 있지만, 실제로는 사적이라는 더 강한 힌트 인 이름 맹 글링을 야기합니다. – chrism1
아니요! 한 줄의 밑줄 문자는 비공개로 만들지 않으며 모듈 수준 변수는 'from foo import *'에서 가져 오지 못하도록합니다. 그렇지 않으면 프라이버시시 '힌트'이외의 다른 효과가 없습니다. –