adi*_*adi 3 python yaml pyyaml
我正在使用PyYAML。有没有一种方法可以定义YAML锚,而不会成为yaml.load加载的数据结构的一部分(我可以从字典中删除“ wifi_parm”,但正在寻找一种更智能的方法)?
example.yaml:
wifi_parm: &wifi_params
ssid: 1
key: 2
test1:
name: connectivity
<<: *wifi_params
test2:
name: connectivity_5ghz
<<: *wifi_params
Run Code Online (Sandbox Code Playgroud)
load_example.py:
import yaml
import pprint
with open('aaa.yaml', 'r') as f:
result = yaml.load(f)
pprint.pprint(result)
Run Code Online (Sandbox Code Playgroud)
印刷品:
{'test1': {'key': 2, 'name': 'connectivity', 'ssid': 1},
'test2': {'key': 2, 'name': 'connectivity_5ghz', 'ssid': 1},
'wifi_parm': {'key': 2, 'ssid': 1}}
Run Code Online (Sandbox Code Playgroud)
我需要:
{'test1': {'key': 2, 'name': 'connectivity', 'ssid': 1},
'test2': {'key': 2, 'name': 'connectivity_5ghz', 'ssid': 1}}
Run Code Online (Sandbox Code Playgroud)
在从中获取结果之前,将丢弃PyYAML中的锚信息yaml.load()。这是根据PyYAML遵循的YAML 1.1规范(...锚名称是序列化详细信息,一旦编写完成就将其丢弃)。在YAML 1.2规范(自2009年起)中,这没有更改。您不能在PyYAML中通过result(递归地)遍历并测试哪些值可能是锚点来执行此操作,而无需大量修改解析器。
在我的ruamel.yaml(即YAML 1.2)的往返模式中,我保留了实际用于别名映射或序列的锚的锚和别名(锚别名目前不为标量保留,也没有“未使用”锚):
import ruamel.yaml
with open('aaa.yaml') as f:
result = ruamel.yaml.round_trip_load(f)
ruamel.yaml.round_trip_dump(result, sys.stdout)
Run Code Online (Sandbox Code Playgroud)
给出:
wifi_parm: &wifi_params
ssid: 1
key: 2
test1:
<<: *wifi_params
name: connectivity
test2:
<<: *wifi_params
name: connectivity_5ghz
Run Code Online (Sandbox Code Playgroud)
您实际上可以遍历映射(或递归地映射树)并找到锚点节点并删除它,而无需知道键名。
import ruamel.yaml
from ruamel.yaml.comments import merge_attrib
with open('aaa.yaml') as f:
result = ruamel.yaml.round_trip_load(f)
keys_to_delete = []
for k in result:
v = result[k]
if v.yaml_anchor():
keys_to_delete.append(k)
for merge_data in v.merge: # update the dict with the merge data
v.update(merge_data[1])
delattr(v, merge_attrib)
for k in keys_to_delete:
del result[k]
ruamel.yaml.round_trip_dump(result, sys.stdout)
Run Code Online (Sandbox Code Playgroud)
给出:
test1:
name: connectivity
ssid: 1
key: 2
test2:
name: connectivity_5ghz
ssid: 1
key: 2
Run Code Online (Sandbox Code Playgroud)
也可以一般地和递归地执行此操作(即,对于树中任意位置的锚和别名)。更新将和上面一样容易,但是您需要跟踪如何删除键,并且不必一定是映射值,它可以是一个序列项。
| 归档时间: |
|
| 查看次数: |
2387 次 |
| 最近记录: |