python 引局部变量-

64 阅读2分钟

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()