如何通过python在.yaml文件中存在的现有数据之间插入数据?

时间:2018-04-19 15:46:36

标签: python yaml pyyaml

我正在尝试使用Python和YAML创建日志记录软件。我需要测试多个电路板,我可能需要每个电路板进行一次以上的试验。 因此,我希望按照电路板编号的升序排列YAML文件中的数据,以自动化分析过程。

#!/usr/bin/python3

import yaml
import io
board_no = (input('Enter the board number: '))
trial_no = (input('Enter the trial no: '))
reading1 = int(input('Reading1: '))
status = input('Pass/Fail: ')
yaml.allow_duplicate_keys = True
basic_info = { 'Board ' + board_no:{
        'Trial ' + trial_no:{
            'Reading1 '  :  reading1,
            'Status ': status
           }
        }
   }
fp = "../yaml_101/test_list.yaml"
outfile = open (fp,'a')
yaml.dump(basic_info, outfile, indent = 4, default_flow_style = False)
outfile.close()

我写这个相当简单的代码只是为了制作日志条目。 我已经找到了在两个块之间插入数据但没有找到的方法。 我当前的输出是(在手动输入之后):

Board 1:
    Trial 1:
        'Reading1 ': 450
        'Status ': Pass
Board 2:
    Trial 1:
        'Reading1 ': 758
        'Status ': Fail
Board 3:
    Trial 1:
        'Reading1 ': 450
        'Status ': Pass
Board 2:
    Trial 2:
        'Reading1 ': 450
        'Status ': Pass

我想要的输出是:

Board 1:
    Trial 1:
        'Reading1 ': 450
        'Status ': Pass
Board 2:
    Trial 1:
        'Reading1 ': 758
        'Status ': Fail
Board 2:
    Trial 2:
        'Reading1 ': 450
        'Status ': Pass
Board 3:
    Trial 1:
        'Reading1 ': 450
        'Status ': Pass

有人可以指导我吗? 我是YAML和Python的新手。

1 个答案:

答案 0 :(得分:0)

您的代码存在一些问题:

  1. 您打开文件以进行追加,但您不想追加,要插入。当然这是可能的,但是你需要知道文件指针的位置,在缓冲区中读取所有内容,编写新内容,然后编写缓冲区。知道文件指针的位置将是困难的部分。

  2. 你做yaml.allow_duplicate_keys = True但在PyYAML中没有做任何事情。这是一个ruamel.yaml功能,允许您使用重复键读取文件(YAML规范不允许这样做,但不合规的PyYAML库会默默忽略)。

    < / LI>
  3. 您不应直接操作YAML文件,并始终使用从YAML加载数据,更新和转储。这样你的YAML就会顺从,即使你的一个输入包含一个或两个引号,或者空格(正如你可以从'Trial '看到的那样,由于空间需要在YAML中引用)。

  4. 您只在YAML文件中使用映射,但这样的试验列表更适合序列。

  5. 您的密钥有枚举信息,这几乎总是一个坏主意,因为您无法预先知道密钥的样子。因此,您应该使用值为Board 1的键Board而不是键1,或者将值作为值的映射,而不是键status.yaml。这样很容易获得特定电路板号的数据(或者如果以相同的方式处理,则更新试验)

  6. 首先,您应该使- Board: 1 Trial: 1 Reading1: 450 Status: Pass - Board: 2 Trial: 1 Reading1: 758 Status: Fail - Board: 3 Trial: 1 Reading1: 450 Status: Pass 文件看起来像:

    Boards:
      - nr: 1
        Trials:
        - nr: 1
          Reading1: 450
          Status: Pass
      - nr: 2
        Trials:
        - nr: 1
          Reading1: 758
          Status: Fail
      - nr: 3
        Trials:
        - nr: 1
          Reading1: 450
          Status: Pass
    

    或使用:

    Boards:
      1:
        Trials:
          1:
            Reading: 450
            Status: Pass
      2:
        Trials:
          1:
            Reading: 758
            Status: Fail
      3:
        Trials:
          1:
             Reading: 450
             Status: Pass
    

    或(我最喜欢的):

    ruamel.yaml

    在第一个示例中,您应该遍历Python列表并插入新的试用版,然后将Board的值更改为大于您的输入板编号。

    要更新上一个示例,请使用from pathlib import Path import ruamel.yaml status_file = Path('status.yaml') yaml = ruamel.yaml.YAML() # yaml.indent(mapping=2) yaml.preserve_quotes = True data = yaml.load(status_file) board_no = 2 # no need to input the trial_no, it should be the next number for this board trials = data['Boards'][board_no]['Trials'] trial_no = sorted(trials.keys())[-1] + 1 reading1 = 450 status = 'Pass' trials[trial_no] = dict(Reading1=reading1, Status=status) yaml.dump(data, status_file) (免责声明我是该程序包的作者),因此映射中的键保持相同的顺序:

    status.yaml

    Boards: 1: Trials: 1: Reading1: 450 Status: Pass 2: Trials: 1: Reading1: 758 Status: Fail 2: Reading1: 450 Status: Pass 3: Trials: 1: Reading1: 450 Status: Pass 更新为:

    for i in range(0, 55):
        print(f"\033[{i}mAt {i} THIS happens! \033[0m")