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
相关产品推荐
相关产品推荐

