You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python:让MainClass的data_history被DataAnalyzer实例访问的正确方式及替代方案

问题描述

我有一个Python类MainClass,包含三个属性:

  • 一个data_history字典,运行时会频繁更新(程序用于分析视频流,基本每帧都会更新);
  • 另外两个对象data_analyzer_00和data_analyzer_01,各自拥有use_data_history()方法,需要使用data_history中的数据。

我需要让data_history能够被这两个分析器对象访问。目前我想到的方法是初始化分析器时传入MainClass实例,代码如下:

class MainClass:
    def __init__(self):
        self.data_history = {}
        self.data_analyzer_00 = DataAnalyzer(self)
        self.data_analyzer_01 = DataAnalyzer(self)

    def update_data_history(self, new_data_history):
        self.data_history = new_data_history

class DataAnalyzer:
    def __init__(self, my_class_instance):
        self.my_class_instance = my_class_instance

    def use_data_history(self):
        # 使用 self.my_class_instance.data_history
        pass

这样可以执行如下操作:

main_obj = MainClass()
main_obj.data_history = {"old_key": "old_value"}
print(main_obj.data_analyzer_00.my_class_instance.data_history)   # 输出旧的data_history
main_obj.update_data_history({"new_key": "new_value"})
print(main_obj.data_analyzer_00.my_class_instance.data_history)   # 输出新的data_history

但我不确定这种方式是否正确,因为会形成循环引用(main_obj包含data_analyzer_00,data_analyzer_00又持有main_obj实例),请问是否有其他实现方式?


解决方案

1. 直接传递data_history引用

既然分析器仅依赖data_history,无需传递整个MainClass实例,直接传入字典引用即可。由于字典是可变对象,若只是修改其内部键值对,分析器能自动获取最新数据;若需要替换整个字典对象,同步更新分析器内的引用即可:

class MainClass:
    def __init__(self):
        self.data_history = {}
        self.data_analyzer_00 = DataAnalyzer(self.data_history)
        self.data_analyzer_01 = DataAnalyzer(self.data_history)

    def update_data_history(self, new_data_history):
        self.data_history = new_data_history
        # 同步更新分析器的字典引用
        self.data_analyzer_00.data_history = self.data_history
        self.data_analyzer_01.data_history = self.data_history

class DataAnalyzer:
    def __init__(self, data_history):
        self.data_history = data_history

    def use_data_history(self):
        # 使用 self.data_history
        pass

2. 调用方法时传入最新数据

每次触发分析逻辑时,主动将当前data_history传给use_data_history方法,完全避免引用依赖,适配视频流每帧更新的场景:

class MainClass:
    def __init__(self):
        self.data_history = {}
        self.data_analyzer_00 = DataAnalyzer()
        self.data_analyzer_01 = DataAnalyzer()

    def update_data_history(self, new_data_history):
        self.data_history = new_data_history

    def run_frame_analysis(self):
        # 每帧分析时传入最新数据
        self.data_analyzer_00.use_data_history(self.data_history)
        self.data_analyzer_01.use_data_history(self.data_history)

class DataAnalyzer:
    def use_data_history(self, data_history):
        # 使用传入的data_history
        pass

3. 观察者模式(适配复杂扩展场景)

如果后续需要新增更多分析器,或者希望data_history更新时自动触发分析,可采用观察者模式实现数据的自动通知:

class MainClass:
    def __init__(self):
        self.data_history = {}
        self._observers = []
        self.data_analyzer_00 = DataAnalyzer()
        self.data_analyzer_01 = DataAnalyzer()
        self._add_observer(self.data_analyzer_00)
        self._add_observer(self.data_analyzer_01)

    def _add_observer(self, observer):
        self._observers.append(observer)

    def update_data_history(self, new_data_history):
        self.data_history = new_data_history
        # 通知所有观察者数据已更新
        for observer in self._observers:
            observer.on_data_updated(self.data_history)

class DataAnalyzer:
    def on_data_updated(self, data_history):
        # 数据更新时自动执行分析
        self.use_data_history(data_history)

    def use_data_history(self, data_history):
        # 使用数据
        pass

关于原方案的循环引用

Python的垃圾回收机制(引用计数+分代回收)可以处理这类循环引用,一般不会引发内存泄漏问题。但如果程序需要长期运行或创建大量此类对象,循环引用可能会轻微延迟内存释放。若追求更简洁的依赖关系,上述三种方案均可避免循环引用。


内容的提问来源于stack exchange,提问作者Carlo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 23:47:35