1. 简要解释报错原因
在plc_data_service.py中声明的global plc_data变量作用域仅限于该模块,其他模块无法直接访问。
2. 详细原因分析
- 变量作用域问题:
global plc_data只是在当前模块中声明了一个全局变量,但这个变量并没有被正确初始化或导出 - 模块间访问限制:Python模块中的全局变量需要通过模块导入才能在其他模块中访问
- 变量未初始化:声明了
global plc_data但没有给它赋初始值 - 赋值位置错误:在函数内部对
plc_data的赋值只是局部变量,不会影响模块级别的变量
3. 修复建议
方案一:正确初始化并导出全局变量
# service/plc_data_service.py
import sys, asyncio, time, datetime
from pathlib import Path
sys.path.append(str(Path(__file__).parent.parent))
from service.plc_opcua_client import OPCUAService
from service.iot_data_service import set_record_data_list
from config.settings import settings
# 正确初始化全局变量
plc_data = None
# 取数据,并将数据存入iotDB
async def fetch_plc_data():
global plc_data # 在函数内部声明使用全局变量
opcua_service = OPCUAService("")
while True:
try:
values = opcua_service.get_values()
values.append(666)
# 获取当前时间
now = datetime.datetime.now()
# 转换为UNIX时间戳
timestamp = time.mktime(now.timetuple())
set_record_data_list(timestamp, settings.opcPLC_opcua_measurements, values)
# 正确更新全局变量
plc_data = values
print('plc_data')
print(plc_data)
print(time.time())
except Exception as e:
print(f"获取数据出错: {e}")
await asyncio.sleep(settings.opcPLC_opcua_time_step) # 每10秒执行一次
方案二:其他模块访问该变量的方式
# 在其他模块中访问plc_data
from service.plc_data_service import plc_data
# 使用时检查是否为None
if plc_data is not None:
print(plc_data)
方案三:提供访问函数(推荐)
# service/plc_data_service.py
# ... 其他代码 ...
# 全局变量和访问函数
plc_data = None
def get_plc_data():
"""获取PLC数据"""
return plc_data
# ... fetch_plc_data函数保持不变,但要确保正确更新全局plc_data ...
# 在其他模块中使用
from service.plc_data_service import get_plc_data
# 获取数据
data = get_plc_data()