如何更改 ruamel.yaml 中对锚点的属性引用之一
How to change one of the attribute reference to anchor in ruamel.yaml
我在我的项目中使用 ruamel.yaml 并且有一个使用锚点的 YAML 文档,有多个地方引用了该锚点。我想在不触及其他地方的情况下更改引用锚点的地方之一的属性之一。
下面的代码详细展示了我想要做什么。
yaml = ruamel.yaml.YAML()
yaml_str = """\
foo: &foo
color: red
length: 599
weight: 32.3
bar:
name: bar_one
params: *foo
anotherbar:
name: bar_another
params: *foo
"""
data = yaml.load(yaml_str)
data["anotherbar"]["params"]["length"] = 39
yaml.dump(data, sys.stdout)
以上代码会输出
foo: &foo
color: red
length: 39
weight: 32.3
bar:
name: bar_one
params: *foo
anotherbar:
name: bar_another
params: *foo
我想更改“anotherbar”中的参数,但它也会更改“bar”。
如果我在分配新值之前复制参数,它会起作用,但它也会复制我不想更改的其他参数:
data["anotherbar"]["params"] = data["anotherbar"]["params"].copy()
data["anotherbar"]["params"]["length"] = 39
yaml.dump(data, sys.stdout)
输出:
foo: &foo
color: red
length: 599
weight: 32.3
bar:
name: bar_one
params: *foo
anotherbar:
name: bar_another
params:
color: red
length: 39
weight: 32.3
但我实际上想要以下 YAML,没有任何重复:
foo: &foo
color: red
length: 599
weight: 32.3
bar:
name: bar_one
params: *foo
anotherbar:
name: bar_another
params:
<<: *foo
length: 39
如何以编程方式获取此合并密钥?
ruamel.yaml 可以往返你想要的输出:
import sys
import io
import ruamel.yaml
yaml_str = """\
foo: &foo
color: red
length: 599
weight: 32.3
anotherbar:
name: bar_another
params:
<<: *foo
length: 39
"""
yaml = ruamel.yaml.YAML()
buf = io.StringIO()
data = yaml.load(yaml_str)
yaml.dump(data, buf)
assert buf.getvalue() == yaml_str
所以可以从你的
实际输入,但没有这样做的内置例程。
params = data["anotherbar"]["params"]
print(type(params))
print(params.merge)
给出:
<class 'ruamel.yaml.comments.CommentedMap'>
[(0, ordereddict([('color', 'red'), ('length', 599), ('weight', 32.3)]))]
那个“ordereddict”实际上是 data["foo"]
对象。
无需复制,您需要创建特殊的字典类型 ruamel.yaml
在内部使用,然后连接合并键并设置 key/value,并附上这个
在数据树中。
import sys
import ruamel.yaml
yaml_str = """\
foo: &foo
color: red
length: 599
weight: 32.3
bar:
name: bar_one
params: *foo
anotherbar:
name: bar_another
params: *foo
"""
yaml = ruamel.yaml.YAML()
data = yaml.load(yaml_str)
upd = ruamel.yaml.comments.CommentedMap() # empty dict like type
data["anotherbar"]["params"] = upd # attach it to the data
upd.add_yaml_merge([(0, data["foo"])]) # attach original dict as merge
upd["length"] = 39 # set the value you want
yaml.dump(data, sys.stdout)
这给了你想要的:
foo: &foo
color: red
length: 599
weight: 32.3
bar:
name: bar_one
params: *foo
anotherbar:
name: bar_another
params:
<<: *foo
length: 39
add_yaml_merge
是构造阶段使用的内部例程
加载。它可能会更改,恕不另行通知,因此请确保固定您的版本
ruamel.yaml 在生产环境中。
我在我的项目中使用 ruamel.yaml 并且有一个使用锚点的 YAML 文档,有多个地方引用了该锚点。我想在不触及其他地方的情况下更改引用锚点的地方之一的属性之一。
下面的代码详细展示了我想要做什么。
yaml = ruamel.yaml.YAML()
yaml_str = """\
foo: &foo
color: red
length: 599
weight: 32.3
bar:
name: bar_one
params: *foo
anotherbar:
name: bar_another
params: *foo
"""
data = yaml.load(yaml_str)
data["anotherbar"]["params"]["length"] = 39
yaml.dump(data, sys.stdout)
以上代码会输出
foo: &foo
color: red
length: 39
weight: 32.3
bar:
name: bar_one
params: *foo
anotherbar:
name: bar_another
params: *foo
我想更改“anotherbar”中的参数,但它也会更改“bar”。
如果我在分配新值之前复制参数,它会起作用,但它也会复制我不想更改的其他参数:
data["anotherbar"]["params"] = data["anotherbar"]["params"].copy()
data["anotherbar"]["params"]["length"] = 39
yaml.dump(data, sys.stdout)
输出:
foo: &foo
color: red
length: 599
weight: 32.3
bar:
name: bar_one
params: *foo
anotherbar:
name: bar_another
params:
color: red
length: 39
weight: 32.3
但我实际上想要以下 YAML,没有任何重复:
foo: &foo
color: red
length: 599
weight: 32.3
bar:
name: bar_one
params: *foo
anotherbar:
name: bar_another
params:
<<: *foo
length: 39
如何以编程方式获取此合并密钥?
ruamel.yaml 可以往返你想要的输出:
import sys
import io
import ruamel.yaml
yaml_str = """\
foo: &foo
color: red
length: 599
weight: 32.3
anotherbar:
name: bar_another
params:
<<: *foo
length: 39
"""
yaml = ruamel.yaml.YAML()
buf = io.StringIO()
data = yaml.load(yaml_str)
yaml.dump(data, buf)
assert buf.getvalue() == yaml_str
所以可以从你的 实际输入,但没有这样做的内置例程。
params = data["anotherbar"]["params"]
print(type(params))
print(params.merge)
给出:
<class 'ruamel.yaml.comments.CommentedMap'>
[(0, ordereddict([('color', 'red'), ('length', 599), ('weight', 32.3)]))]
那个“ordereddict”实际上是 data["foo"]
对象。
无需复制,您需要创建特殊的字典类型 ruamel.yaml 在内部使用,然后连接合并键并设置 key/value,并附上这个 在数据树中。
import sys
import ruamel.yaml
yaml_str = """\
foo: &foo
color: red
length: 599
weight: 32.3
bar:
name: bar_one
params: *foo
anotherbar:
name: bar_another
params: *foo
"""
yaml = ruamel.yaml.YAML()
data = yaml.load(yaml_str)
upd = ruamel.yaml.comments.CommentedMap() # empty dict like type
data["anotherbar"]["params"] = upd # attach it to the data
upd.add_yaml_merge([(0, data["foo"])]) # attach original dict as merge
upd["length"] = 39 # set the value you want
yaml.dump(data, sys.stdout)
这给了你想要的:
foo: &foo
color: red
length: 599
weight: 32.3
bar:
name: bar_one
params: *foo
anotherbar:
name: bar_another
params:
<<: *foo
length: 39
add_yaml_merge
是构造阶段使用的内部例程
加载。它可能会更改,恕不另行通知,因此请确保固定您的版本
ruamel.yaml 在生产环境中。