Python写入CSV文件为空无报错,请求问题排查帮助
问题分析与修复方案
1. 核心问题:未收集全必要数据就写入CSV,变量未初始化
你的代码在每次循环中都会尝试调用position函数并写入CSV,但此时D1、D2、D3可能还没全部从串口获取到有效值,甚至程序刚启动时这些变量根本没被定义。这会导致两种情况:
- 若串口还未返回对应数据,
listeDonnees可能为空列表,访问listeDonnees[2]会触发IndexError(如果程序没崩溃,大概率是你没看到报错,或串口一直有数据但未覆盖三个变量) - 即使没报错,写入CSV的也是未初始化的变量值或错误计算结果,若程序因报错终止,CSV文件只会保留表头,后续内容无法写入
2. 次要问题:文件频繁打开关闭的性能隐患
每次循环都打开/关闭CSV文件,虽语法合法,但会带来不必要的性能开销,建议在循环外保持文件打开状态,或仅在获取完整数据时写入。
3. 潜在问题:串口函数鲁棒性不足
recup_port_Arduino函数中,如果遍历串口时没找到包含COM9的端口,mData变量未定义就执行print(mData.is_open),会直接报错。
修复后的代码
import serial import serial.tools.list_ports import numpy as np import csv header1 = "x_value" header2 = "y_value" header3 = "z_value" fieldnames = [header1, header2, header3] # 初始化变量,避免未定义报错 D1 = D2 = D3 = None def recup_port_Arduino(): ports = list(serial.tools.list_ports.comports()) mData = None for p in ports: print(p) if 'COM9' in p.description: mData = serial.Serial(p.device, 115200) break # 找到目标串口后立即退出循环 if not mData: raise Exception("未找到Arduino串口COM9") print(mData.is_open) print(mData.name) return mData def position(D1,D2,D3,y2,x3): y = -(D2**2 - D1**2 - y2**2)/(2*y2) x = -(D3**2 - D1**2 - x3**2)/(2*x3) z = np.sqrt(D1**2 - x**2 - y**2) return x,y,z Data = recup_port_Arduino() # 在循环外打开CSV文件,保持打开状态直到程序终止 with open('Position.csv', 'w', newline='') as csv_file: csv_writer = csv.DictWriter(csv_file, fieldnames=fieldnames) csv_writer.writeheader() while True: line1 = Data.readline() if not line1: continue # 跳过空行 listeDonnees = line1.split() # 先判断列表长度,避免索引越界 if len(listeDonnees) < 3: continue try: if listeDonnees[2] == b'2': if len(listeDonnees) >=5: D2 = float(listeDonnees[4].decode()) print(f'D2 = {D2}') elif listeDonnees[2] == b'3': if len(listeDonnees) >=5: D3 = float(listeDonnees[4].decode()) print(f'D3 = {D3}') elif listeDonnees[2] == b'm': if len(listeDonnees) >=2: D1 = float(listeDonnees[1].decode()) print(f'D1 = {D1}') except (ValueError, IndexError): print("串口数据格式错误,跳过当前行") continue # 只有当三个变量都获取到有效值时,才计算并写入CSV if all(v is not None for v in [D1, D2, D3]): try: x_value, y_value, z_value = position(D1, D2, D3, 0.75, 0.75) info = { header1: x_value, header2: y_value, header3: z_value } csv_writer.writerow(info) csv_file.flush() # 立即刷新缓冲区,确保数据写入磁盘 print(x_value, y_value, z_value) except ValueError as e: print(f"计算位置时出错:{e}")
关键修复点说明
- 变量初始化:提前将
D1/D2/D3设为None,避免未定义报错 - 数据完整性判断:仅当三个变量都有有效值时,才执行计算和写入操作
- 鲁棒性处理:增加列表长度判断、异常捕获,避免串口数据格式错误导致程序崩溃
- 文件操作优化:在循环外打开CSV文件,每次写入后手动刷新缓冲区,确保数据及时写入磁盘
- 串口函数修复:增加
mData空值判断,避免未找到串口时直接报错
内容的提问来源于stack exchange,提问作者Herisfal
相关产品推荐
相关产品推荐

