css3
V2EX  ›  程序员

Python Borg pattern 模式疑问

By css3 at 2022 年 6 月 29 日 · 1940 次点击
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"} 这是为什么?

6 条回复  •  2022-06-29 16:06:31 +08:00
lonelinsky
   1
lonelinsky  
   2022 年 6 月 29 日
主要就是这行的原因 self.__dict__ = self._shared_state

参考这里 https://docs.python.org/3/library/stdtypes.html#object.__dict__
ruanimal
   2
ruanimal  
   2022 年 6 月 29 日
因为 Python 中一切都是对象,self.xx == self.__dict__['xx']

ps: 代码的坏味道非常浓。。
css3
   3
css3  
OP
   2022 年 6 月 29 日
@lonelinsky 我是不理解的是_shared_state: {}为啥会被更新为 _shared_state: {"state": "Init"}, 代码里边并没有更新_shared_state 的语句, 你发的是后面一句了

@ruanimal 那不应该是__dict__里边多一个 {"state": "Init"} 而已, 为啥却被更新到_shared_state 上去了?
lonelinsky
   4
lonelinsky  
   2022 年 6 月 29 日
@css3

self.state = "Init"
=> self.__dict__["state"] = "Init" # 参见上一条回复提到的文档
=> self._shared_state["state"] = "Init" # self.__dict__ = self._shared_state
ruanimal
   5
ruanimal  
   2022 年 6 月 29 日
@css3 因为你写了 self.__dict__ = self._shared_state ,导致所有实例都是都是引用的同一个_shared_state

建议区分一下类属性、实例属性
Via8veritas
   6
Via8veritas  
   2022 年 6 月 29 日
@css3 字典是引用类型,所以在赋值后,实际上__dict__和_shared_state 此时是指向同一块空间。
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
© 2026 V2EX · 43ms · 3.9.8.5