我在python中实现borg时遇到问题。我在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()
我认为这是打印“Hello”,但对我来说它只是打印一个空白行。任何想法为什么会这样?
答案 0 :(得分:13)
看起来它工作得太好了: - )
问题在于self.__myvalue = ""
中的作业__init__
每次创建新的Borg时都会破坏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__
中的一些代码来初始化myvalue
的值(如果它还不存在),或者至少处理它可能不存在于getter中。也许是这样的事情:
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 :(得分: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()
答案 2 :(得分:1)
问题似乎是init()正在将myvalue重置为空字符串。当我删除该行时,我得到了预期的输出。
答案 3 :(得分: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)
答案 4 :(得分: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.
答案 5 :(得分: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
答案 6 :(得分:0)
尝试
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
if self.__we_are_one:
return
self.__myvalue = ""
def myvalue(self, value=None):
if value:
self.__myvalue = value
return self.__myvalue
conf = Config()
conf.myvalue("Hello") # print "Hello"
conf2 = Config()
print conf2.myvalue() # print "Hello"