Python Borg pattern 模式疑问

2022-06-29 15:05:06 +08:00
 css3
from typing import Dict


class Borg:
    _shared_state: Dict[str, str] = {}

    def __init__(self):
        self.__dict__ = self._shared_state


class YourBorg(Borg):
    def __init__(self, state=None):
        super().__init__()
        if state:
            self.state = state
        else:
            # initiate the first instance with default state
            if not hasattr(self, "state"):
                self.state = "Init"   # 这里为什么会更新到 _shared_state 的 value 中

    def __str__(self):
        return self.state

第 19 行, self.state = "Init" 后, 会将_shared_state: {}, 更新为 _shared_state: {"state": "Init"} 这是为什么?

916 次点击
所在节点    程序员
6 条回复
lonelinsky
2022-06-29 15:18:28 +08:00
主要就是这行的原因 self.__dict__ = self._shared_state

参考这里 https://docs.python.org/3/library/stdtypes.html#object.__dict__
ruanimal
2022-06-29 15:19:53 +08:00
因为 Python 中一切都是对象,self.xx == self.__dict__['xx']

ps: 代码的坏味道非常浓。。
css3
2022-06-29 15:57:26 +08:00
@lonelinsky 我是不理解的是_shared_state: {}为啥会被更新为 _shared_state: {"state": "Init"}, 代码里边并没有更新_shared_state 的语句, 你发的是后面一句了

@ruanimal 那不应该是__dict__里边多一个 {"state": "Init"} 而已, 为啥却被更新到_shared_state 上去了?
lonelinsky
2022-06-29 16:02:16 +08:00
@css3

self.state = "Init"
=> self.__dict__["state"] = "Init" # 参见上一条回复提到的文档
=> self._shared_state["state"] = "Init" # self.__dict__ = self._shared_state
ruanimal
2022-06-29 16:05:39 +08:00
@css3 因为你写了 self.__dict__ = self._shared_state ,导致所有实例都是都是引用的同一个_shared_state

建议区分一下类属性、实例属性
Via8veritas
2022-06-29 16:06:31 +08:00
@css3 字典是引用类型,所以在赋值后,实际上__dict__和_shared_state 此时是指向同一块空间。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/862937

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX