Python-borg模式问题

Python-borg模式问题,python,design-patterns,Python,Design Patterns,我在python中实现borg时遇到问题。我在答案中找到了一个例子,但它对我不起作用,除非我遗漏了什么。代码如下: class Config: """ Borg singleton config object """ __we_are_one = {} __myvalue = "" def __init__(self): #implement the borg pattern (we are one) self.

我在python中实现borg时遇到问题。我在答案中找到了一个例子,但它对我不起作用,除非我遗漏了什么。代码如下:


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

我想这是为了打印“你好”,但对我来说,它只是打印一个空行。知道为什么会这样吗?

问题似乎是init()正在将myvalue重置为空字符串。当我删除该行时,我得到了预期的输出。

它似乎工作得太好了:-)

问题是,每次创建一个新的博格时,
\uuu init\uuuu
中的赋值
self.\uuu 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.\uu myvalue
一切都会好起来的

话虽如此,
myvalue()
的实现还是有点奇怪。我认为,更好的方法是使用属性来显式地使用getter和setter。您还需要
\uuuu init\uuuu
中的一些代码来初始化
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

将删除
self.\uuu myvalue=”“
与以及避免变量名中出现
\uuuu
的建议相结合,我们得到:

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):
    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
试试这个

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"

为什么要对属性使用双重名称?只需一个前导就可以使它成为“私有的”。我从我链接的另一个问题中复制了代码。但不管怎样,我认为一个单数表示它是私有的,而一个双数表示它会导致名称损坏,这是一个更强烈的暗示,它确实是私有的,尽管如果用户确定,它仍然可以访问。不!单前导下划线不会使它们成为私有的,只会使其不在“from foo import*”上导入模块级变量,否则,它除了“提示”隐私之外没有任何效果。感谢大家的提醒,我更正了另一个示例。名称混乱没有任何帮助。使用单个前导是“private”的一种广泛使用的约定(它不是Java风格或C++风格的private)。这是传统意义上的“私人”。哈!很明显,真的,应该已经发现了。谢谢所有的提示。我认为这个Borg实现不适用于新样式的类。我遗漏了什么吗?@legesh它在Python 2.6中似乎工作得很好。也许我错过了什么。。。什么样的信息或经验让你暂停使用新样式的类?你能在代码中添加一些解释吗。一般来说,我们尝试不只是“解决”某人的问题,而是给他们工具来理解他们需要做什么。
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
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"