英文:
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文件的官方推荐扩展名一直是
.yaml
。YML格式基于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 apathlib.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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论