You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Python在已有YAML文件中插入数据及日志软件开发需求

解答:Python操作YAML的两个电路板日志需求问题

我来帮你搞定这两个和YAML操作相关的问题,都是电路板测试日志场景里的常见需求,直接上实用的方案:


问题1:如何在已有YAML文件的现有数据之间插入数据?

YAML本质是序列化的数据结构,直接修改文本文件容易出错,最稳妥的方式是先把YAML加载成Python的字典/列表,在内存里修改后再写回文件。举个具体的例子:

假设你现有boards.yaml的内容是这样的:

boards:
  - board_no: "001"
    trials:
      - trial_no: "1"
        reading1: 100
        status: "Pass"
  - board_no: "003"
    trials:
      - trial_no: "1"
        reading1: 95
        status: "Pass"

现在要在001和003之间插入编号为002的电路板数据,代码可以这么写:

import yaml

# 1. 加载现有YAML文件到Python对象
with open('boards.yaml', 'r') as f:
    data = yaml.safe_load(f)

# 2. 准备要插入的新电路板数据
new_board = {
    "board_no": "002",
    "trials": [
        {
            "trial_no": "1",
            "reading1": 98,
            "status": "Pass"
        }
    ]
}

# 3. 找到合适的插入位置(按board_no升序插入)
boards_list = data['boards']
insert_index = 0
for idx, board in enumerate(boards_list):
    # 比较编号,找到第一个比新编号大的位置
    if board['board_no'] > new_board['board_no']:
        insert_index = idx
        break
else:
    # 如果所有编号都比新的小,就插在末尾
    insert_index = len(boards_list)

boards_list.insert(insert_index, new_board)

# 4. 写回YAML文件,保持原有格式
with open('boards.yaml', 'w') as f:
    yaml.dump(data, f, sort_keys=False, default_flow_style=False)

关键细节:

  • sort_keys=False:避免yaml自动给键排序,保持你想要的字段顺序
  • default_flow_style=False:让输出是可读性高的块格式,而不是紧凑的流格式
  • 如果你的YAML结构不是嵌套在boards下(比如直接是一个列表),只要调整对应的数据操作逻辑就行

问题2:将YAML日志按电路板编号升序排列,同时支持多次测试记录

结合你给出的代码片段,我帮你完善成一个完整的流程:每次输入测试数据时,自动对应到已有电路板(没有就新建),然后整体按电路板编号升序排序,最后保存到YAML文件。

完整代码如下:

#!/usr/bin/python3
import yaml

def load_test_logs(file_path='test_logs.yaml'):
    """加载现有YAML日志文件,处理文件不存在或为空的情况"""
    try:
        with open(file_path, 'r') as f:
            data = yaml.safe_load(f)
            # 初始化默认结构
            if not data or 'boards' not in data:
                return {'boards': []}
            return data
    except FileNotFoundError:
        # 文件不存在时直接返回空结构
        return {'boards': []}

def save_test_logs(data, file_path='test_logs.yaml'):
    """将数据保存回YAML文件,保持格式可读性"""
    with open(file_path, 'w') as f:
        yaml.dump(data, f, sort_keys=False, default_flow_style=False)

def main():
    # 获取用户输入
    board_no = input('Enter the board number: ')
    trial_no = input('Enter the trial no: ')
    reading1 = int(input('Reading1: '))
    status = input('Pass/Fail: ')

    # 加载现有日志数据
    log_data = load_test_logs()
    boards = log_data['boards']

    # 检查当前电路板是否已有记录
    target_board = None
    for board in boards:
        if board['board_no'] == board_no:
            target_board = board
            break

    # 准备新的测试记录
    new_trial = {
        'trial_no': trial_no,
        'reading1': reading1,
        'status': status
    }

    if target_board:
        # 已有该电路板,添加新测试记录
        target_board.setdefault('trials', []).append(new_trial)
    else:
        # 没有该电路板,创建新条目
        new_board = {
            'board_no': board_no,
            'trials': [new_trial]
        }
        boards.append(new_board)

    # 按电路板编号升序排序
    # 如果你的编号是纯数字,用key=lambda x: int(x['board_no'])更准确
    boards.sort(key=lambda x: x['board_no'])

    # 保存更新后的日志
    save_test_logs(log_data)
    print(f"Test record added! Board {board_no} is sorted correctly.")

if __name__ == '__main__':
    main()

关键细节:

  • load_test_logs函数:处理文件不存在或内容为空的边界情况,避免程序报错
  • setdefault('trials', []):确保即使电路板还没有测试记录,也能安全添加新的trial
  • 排序逻辑:如果你的电路板编号是带前导零的字符串(比如"001"),直接按字符串排序就有效;如果是数字和字符串混合,建议转成整数再排序(修改sort的key参数即可)
  • 全程保持YAML格式的可读性,避免自动排序破坏日志结构

内容的提问来源于stack exchange,提问作者Tejas Vasekar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:11:51