第70篇 Python文件与数据处理:面试官问“实验日志怎么解析”,别只会手动split
前面Python基础过了一遍今天聊文件和数据处理的实操内容。机器人开发中经常要和三类文件打交道CSV格式的传感器日志、JSON格式的配置文件和通信数据、YAML格式的ROS2参数文件。这三种格式的读写是基本功面试的时候经常被问到。先说个真实场景。老板跑过来跟你说昨天跑了一晚上的实验数据都在那个CSV里你帮我分析一下成功率。你打开文件一看几万行数据每行是时间戳、物体ID、抓取姿态、成功/失败。手动看不可能。用Excel打开卡死了。这时候Python就派上用场了。几十行代码读取、分析、出图一气呵成。CSV传感器日志的标准格式CSV是最简单的表格数据格式。Python内置了csv模块import csv # 读取 with open(grasp_log.csv, r) as f: reader csv.DictReader(f) for row in reader: print(row[object_id], row[success]) # 写入 with open(results.csv, w, newline) as f: writer csv.writer(f) writer.writerow([object_id, success, time]) writer.writerow([cup, True, 2026-07-09 14:30:00])DictReader比普通的reader好用——它自动把第一行当列名每行数据返回一个dict用列名访问比用索引清晰得多。实际项目中CSV文件经常有编码问题。中文路径、中文注释在Windows上特别容易出问题。建议统一用UTF-8编码with open(data.csv, r, encodingutf-8) as f: reader csv.DictReader(f)如果数据量大几百万行csv模块会比较慢。这时候可以上pandas后面会专门讲。JSON通信和配置的标准格式JSON是机器人系统中最常见的数据交换格式。ROS2的很多接口、API的返回值、配置文件都用JSON。Python处理JSON非常简单import json # 读取 with open(config.json, r) as f: config json.load(f) # 写入 config[max_speed] 1.5 with open(config.json, w) as f: json.dump(config, f, indent2) # 字符串和对象之间转换 json_str json.dumps(config, ensure_asciiFalse) obj json.loads(json_str)indent2让输出格式化方便阅读。ensure_asciiFalse让中文正常显示而不是变成Unicode转义。一个容易踩的坑JSON的key必须是字符串。如果你的dict用了int或tuple做keyjson.dump会报错。解决方法是在序列化之前把key转成字符串。还有一个实用的技巧处理嵌套JSON时用json.loads配合递归提取需要的字段def extract_field(data, field, defaultNone): 从嵌套dict中安全地提取字段 keys field.split(.) for key in keys: if isinstance(data, dict): data data.get(key, default) else: return default return data # 用法 speed extract_field(response, robot.status.max_speed, 0.0)YAMLROS2的配置语言如果你用ROS2YAML是绕不过去的。ROS2的参数文件、Launch文件中的参数配置都是YAML格式。Python处理YAML需要安装PyYAML库pip install pyyaml。import yaml # 读取 with open(params.yaml, r) as f: params yaml.safe_load(f) # 写入 with open(output.yaml, w) as f: yaml.dump(params, f, default_flow_styleFalse)注意一定要用yaml.safe_load而不是yaml.load。后者有安全风险——恶意的YAML文件可以执行任意Python代码。safe_load限制了可反序列化的类型避免了这个问题。一个典型的ROS2参数YAML文件长这样lidar_node: ros__parameters: scan_range: 30.0 scan_freq: 10 port: /dev/ttyUSB0读取后就是一个嵌套dictparams[lidar_node][ros__parameters][scan_range]。路径处理os.path vs pathlib处理文件路径Python有两个选择传统的os.path和现代的pathlib。推荐用pathlib——它是面向对象的用起来更直观from pathlib import Path # 拼接路径 data_dir Path(/home/user/robot_data) log_file data_dir / logs / scan_001.csv # 检查文件是否存在 if log_file.exists(): print(fFile size: {log_file.stat().st_size} bytes) # 遍历目录下所有CSV文件 for csv_file in data_dir.glob(**/*.csv): print(csv_file.name) # 读取文件内容 lines log_file.read_text().splitlines()pathlib的/运算符用来拼接路径glob支持递归搜索read_text和write_text一行搞定文件读写。比os.path那一堆字符串操作优雅太多。大文件处理的注意事项当CSV文件超过百万行的时候csv模块会变得很慢。这时候有两个选择一是用pandas的read_csv它底层是C实现速度快很多二是用生成器逐行读取避免一次性把整个文件加载到内存。# 生成器方式内存友好 def read_large_csv(filepath): with open(filepath, r, encodingutf-8) as f: reader csv.DictReader(f) for row in reader: yield row # 每次只返回一行 # 使用 for row in read_large_csv(million_rows.csv): process(row)还有一个常见坑写入CSV时忘记加newline参数在Windows上会多出空行。加上newline让csv模块自己控制换行就不会出这个问题。补充一个实际工作中经常遇到的场景解析机器人日志文件。很多硬件设备输出的日志格式不是标准的CSV或JSON而是自定义的文本格式。这时候需要用正则表达式配合文件处理来提取数据。Python的re模块非常强大建议花点时间熟悉常用的正则语法在实际工作中这个技能特别实用。给正在准备面试的你文件处理在面试中不算高频考点但在实际工作中是每天都要用的。建议你把CSV、JSON、YAML的读写都练一遍特别是pathlib的使用。面试的时候如果聊到数据处理能自然地提到这些工具说明你有实际项目经验。下篇进入NumPy的世界——机器人数据处理的Python标配。NumPy是Python科学计算的基石做矩阵运算、处理传感器数据、跑深度学习模型都离不开它。如果这篇文章对你有帮助欢迎点赞、在看、转发三连。 你的支持是我持续更新的最大动力。「机器人软件开发面试·从入门到精通」连载系列上一篇第69篇 Python面向对象——和C的对比理解下一篇预告第71篇 NumPy入门——机器人数据处理的Python标配有任何问题欢迎评论区留言我会尽量回复。