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

如何在多脚本中实时重载被修改的同一Python对象?

问题描述

有一个类实例 c = C() 被程序的多个脚本导入。运行时,某一脚本通过数据库操作修改了 c 的属性 x(即 c.x = y),希望其他同时运行的脚本能立即感知到该变更,无需重启使用 c 的脚本,在所有使用位置重载内存中的 c。已了解Python的reload()函数可重载模块,但希望仅在c.x被修改时,通知所有导入c的文件重载它。已知同一脚本内修改c.x会立即生效,但跨脚本的实例同步无法实现。

解决方案

1. 属性代理+数据库轮询(轻量方案)

不让脚本直接持有c的实例,而是封装获取c.x的代理方法,每次访问x时都从数据库拉取最新值:

# 定义C类的模块中
class C:
    def __init__(self):
        # 初始化从数据库加载x
        self._x = self._load_x_from_db()
    
    def _load_x_from_db(self):
        # 实现从数据库读取x的逻辑
        db_query_result = ...
        return db_query_result
    
    @property
    def x(self):
        # 每次访问x都重新从数据库拉取
        return self._load_x_from_db()
    
    @x.setter
    def x(self, value):
        # 修改x时同步更新数据库
        self._update_x_to_db(value)
        self._x = value

所有脚本访问c.x时拿到的都是最新值,无需重载实例或通知其他脚本。

2. 发布-订阅模式(主动通知)

如果需要主动通知其他脚本更新实例,可通过消息队列或本地套接字实现发布订阅:

  • 发布端:当c.x被修改时,发送更新消息到消息通道(比如Redis的Pub/Sub、本地UDP套接字)
  • 订阅端:每个导入c的脚本启动时订阅通道,收到更新消息后重新加载c的属性或重载模块:
# 订阅端脚本示例
import importlib
import my_module  # 定义C类和c实例的模块
import redis

r = redis.Redis()
pubsub = r.pubsub()
pubsub.subscribe('c_x_update')

def handle_update(message):
    # 重载模块并重新获取c实例
    importlib.reload(my_module)
    global c
    c = my_module.c

# 后台线程监听消息
import threading
threading.Thread(target=lambda: pubsub.listen(), daemon=True).start()

发布端修改c.x后执行:

r.publish('c_x_update', 'x_updated')

3. 共享内存(适用于同一机器多进程)

如果脚本是同一机器上的多进程,可用multiprocessing.Manager创建共享实例:

# 主进程中创建共享实例
from multiprocessing import Manager
import my_module

manager = Manager()
shared_c = manager.C()  # 要求C类可序列化,或自定义共享类
# 将shared_c导出给其他脚本使用

所有进程修改shared_c.x时,其他进程访问的都是同一共享内存中的值,自动同步。

注意:reload()仅能重载模块,若其他脚本已将c导入自身命名空间(如from my_module import c),重载模块后需重新导入c才会生效,因此直接用reload()的可靠性不如上述方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 22:52:12