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

Python中WebSocket回调访问全局变量的同步机制问题

问题描述

我正在使用一个提供WebSocket持续消息流功能的第三方API,希望在on_message()函数外部定义的Live_Data、Prev_Data等变量能被该函数访问,代码结构如下:

soc = WebSocket()

Live_Data = {}
Prev_Data = {}
def on_message(ws, message):
    if <check condition about Prev_Data>:
        <Do something on Prev_Data and Live_Data>
            
def on_open(ws):
    print("on open")

def on_error(ws, error):
    print(error)
    
def on_close(ws):
    print("Close")

# Assign the callbacks.
soc._on_open = on_open
soc._on_message = on_message
soc._on_error = on_error
soc._on_close = on_close

soc.connect()

运行时出现错误:

Prev_data is referenced before it is assigned

推测原因是on_message()方法异步执行,后续调用可能在首次调用完成写入Prev_Data前就尝试访问它。需要了解同步访问Prev_Data及同类变量的机制。

补充说明:完全不使用Prev_Data时,代码运行正常。

解决方案

1. 修正变量作用域问题

错误的直接原因大概率是在on_message内部对Prev_Data做了赋值操作(比如Prev_Data = new_val),Python会将其视为局部变量,从而触发“引用前未赋值”的错误。此时需要用global关键字声明变量为全局变量:

def on_message(ws, message):
    global Prev_Data, Live_Data
    if <check condition about Prev_Data>:
        <Do something on Prev_Data and Live_Data>
        # 示例赋值操作
        Prev_Data = Live_Data.copy()

2. 线程安全同步机制

WebSocket回调通常在独立线程中执行,多个on_message调用可能并发访问、修改全局变量,必须通过锁保证线程安全:
使用threading.Lock实现互斥访问,确保同一时间只有一个线程能操作变量:

import threading

soc = WebSocket()

Live_Data = {}
Prev_Data = {}
data_lock = threading.Lock()

def on_message(ws, message):
    global Prev_Data, Live_Data
    # 使用with语句自动管理锁的获取与释放
    with data_lock:
        current_data = <解析message得到的数据>
        # 先判断Prev_Data是否已初始化
        if Prev_Data:
            <执行依赖Prev_Data的逻辑>
        # 更新数据
        Live_Data = current_data
        Prev_Data = current_data.copy()

3. 初始化校验

首次调用on_message时Prev_Data为空字典,可通过初始化校验跳过依赖逻辑,避免空值引发的异常:

def on_message(ws, message):
    global Prev_Data, Live_Data
    with data_lock:
        current_data = <解析message得到的数据>
        # 首次调用时跳过依赖Prev_Data的操作
        if bool(Prev_Data):
            <处理Prev_Data与current_data的逻辑>
        # 更新历史数据
        Prev_Data = current_data.copy()
        Live_Data = current_data

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 08:35:32