Python borg模式问题

时间:2009-04-14 14:17:37

标签: python design-patterns

我在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”,但对我来说它只是打印一个空白行。任何想法为什么会这样?

7 个答案:

答案 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"