如何使用ruamel.yaml从Python编写配方文件到yml文档。

huangapple go评论103阅读模式
英文:

How to write recipe files to a yml doc from Python using ruamel.yaml

问题

我正在尝试编写一个脚本,该脚本将接受参数并将其写入一个yml文件,以便我可以运行Snowfakery查询。Snowfakery要求前几行是配方行,其余的行不需要-

- snowfakery_version: version
- object: obj
  fields:
     name: John Doe

我尝试过以下方法:

snowfakeryTest = {
    "- snowfakery_version": 3,
    "- object": "obj",
    "fields":{
        "name": "John Doe"
    }
}

with open("simple.yml", 'w') as outfile:
    yaml_dump(snowfakeryTest, outfile,)

但生成的yml总是看起来像提供的图像在这里输入图像描述

英文:

I am trying to write a script that will take arguments and write it to a yml file so i can run a snowfakery query. Snowfakery requires the first few lines be recipe lines and the rest of the lines do not need -

- snowfakery_version: version
- object: obj
  fields:
     name: John Doe

I have tried

snowfakeryTest = {
    "- snowfakery_version": 3,
    "- object": "obj",
    "fields":{
        "name": "John doe"
    }
}

with open("simple.yml", 'w') as outfile:
    yaml_dump(snowfakeryTest, outfile,)

but the yml that is generate always looks like the image provided
enter image description here

答案1

得分: 0

YAML是数据结构的表示方式。您需要在内存中创建相应的数据结构,并将其传递给yaml_dump

您的示例文档显示了一个外部数据结构,它是一个列表;它包含两个字典(第二个字典包含一个嵌套字典)。在Python中,它将是这样的:

snowfakeryTest = [
  {"snowfakery_version": "version"},
  {
    "object": "obj",
    "fields": {
      "name": "John Doe",
    },
  }
]

如果我们将其转储(我使用PyYAML而不是ruamel.yaml),我们得到:

- snowfakery_version: version
- fields:
    name: John Doe
  object: obj
英文:

YAML is a representation of a data structure. You need to create the appropriate data structure in memory and pass that to yaml_dump.

Your example document shows an outer data structure that's a list; it contains two dictionaries (and the second dictionary contains a nested dictionary). In Python, that would be:

snowfakeryTest = [
  {"snowfakery_version": "version"},
  {
    "object": "obj",
    "fields": {
      "name": "John Doe",
    },
  }
]

If we dump that (I'm using PyYAML instead of ruamel.yaml), we get:

- snowfakery_version: version
- fields:
    name: John Doe
  object: obj

答案2

得分: 0

YAML文档由标量(各种形式的字符串,某些未引用的标量被加载为整数、浮点数、布尔值、日期时间等)、映射(通常在Python中加载为dict)和序列(通常在Python中加载为list)组成。您需要的输出是一个根级序列,其中包含嵌套的映射作为元素。YAML中的这些元素(以块样式表示)以破折号(- + 空格)开头,您不需要自己提供这些。

面对不符合要求的YAML输出,通常有助于加载期望的输出并检查生成的数据结构:

import ruamel.yaml

yaml_str = """\
- snowfakery_version: version
- object: obj
  fields:
     name: John Doe
"""
    
yaml = ruamel.yaml.YAML()
data = yaml.load(yaml_str)
print(data)

输出如下:

[{'snowfakery_version': 'version'}, {'object': 'obj', 'fields': {'name': 'John Doe'}}]

在这个简单的情况下,您可以直接复制粘贴输出到您的程序中以定义数据结构,但添加一些换行符和额外的逗号可以使其更易读和可扩展:

import sys
from pathlib import Path
import ruamel.yaml

snowfakeryTest = [
  {'snowfakery_version': 'version'},
  {'object': 'obj',
   'fields': {'name': 'John Doe'},
  }
]

out_file = Path('simple.yaml')

yaml = ruamel.yaml.YAML()
yaml = yaml.dump(snowfakeryTest, out_file)

print(out_file.read_text())

输出如下:

- snowfakery_version: version
- object: obj
  fields:
    name: John Doe

一些注意事项:

  • ruamel.yaml 输出到UTF-8流,这是二进制的,所以最好使用'wb'来打开输出文件。使用pathlib.Path实例而不是流参数会为您执行此操作。
  • 自至少2006年9月以来,YAML文件的官方推荐扩展名一直是.yamlYML格式基于XML,看起来完全不同。
  • 输出中键的顺序与您在Python dict 中指定的顺序相同。尽管根据YAML规范,键的顺序应该无关紧要,但具有可预测的顺序对于存储在版本控制系统中的文档可能很重要。
英文:

YAML documents consist of scalars (strings of various forms, with some unquoted scalars loaded as integers,
float, booleans, datetime, etc.), mappings (normally loaded as dict in Python) and sequences (normally loaded as Python list)
Your required output consists of a root level sequence, containing (nested) mappings as elements. These elements in YAML (in block
style) are preceded by dashes (- + space), and you should not provide those yourself.

Faced with YAML output that doesn't look as required, it is often helpful to load the expected output and inspect
the resulting data structure:

import ruamel.yaml

yaml_str = """\
- snowfakery_version: version
- object: obj
  fields:
     name: John Doe
"""
    
yaml = ruamel.yaml.YAML()
data = yaml.load(yaml_str)
print(data)

which gives:

[{'snowfakery_version': 'version'}, {'object': 'obj', 'fields': {'name': 'John Doe'}}]

In this simple case you can directly copy-paste the output in your program to define the data structure, but a few
newlines and an extra comma make it more readable and extendable:

import sys
from pathlib import Path
import ruamel.yaml

snowfakeryTest = [
  {'snowfakery_version': 'version'},
  {'object': 'obj',
   'fields': {'name': 'John Doe'},
  }
]

out_file = Path('simple.yaml')

yaml = ruamel.yaml.YAML()
yaml = yaml.dump(snowfakeryTest, out_file)

print(out_file.read_text())

which gives:

- snowfakery_version: version
- object: obj
  fields:
    name: John Doe

A few notes:

  • ruamel.yaml outputs to a UTF-8 stream, which is binary, so you should preferably use 'wb' to open
    the output file. Providing a pathlib.Path instance instead of a stream argument does that for you.
  • The officially recommeded extension for YAML files has been .yaml since at least September 2006.
    The YML format is XML based and looks completely different
  • the order of keys in the output is the same as what you specify in your Python dict. Although
    key order should be insignificant according to the YAML spec, having a predictable order can be important for
    documents stored in versioning systems.

huangapple
  • 本文由 发表于 2023年6月29日 05:07:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/76576708.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定