是否可以在YAML中进行字符串替换?
有没有办法在YAML中替换字符串。例如,我想定义一次是否可以在YAML中进行字符串替换?,yaml,Yaml,有没有办法在YAML中替换字符串。例如,我想定义一次sub,并在整个YAML文件中使用它 sub: ['a', 'b', 'c'] command: params: cmd1: type: string enum : # Get the list defined in 'sub' description: Exclude commands from the test list. c
sub
,并在整个YAML文件中使用它
sub: ['a', 'b', 'c']
command:
params:
cmd1:
type: string
enum : # Get the list defined in 'sub'
description: Exclude commands from the test list.
cmd2:
type: string
enum: # Get the list defined in 'sub'
在YAML中不能真正替换字符串值,例如用另一个子字符串“”替换某个字符串的子字符串。然而,YAML确实有可能将一个节点(在您的例子中是列表['a'、'b'、'c'])标记为一个,并将其重新用作一个 锚定采用
&some\u id
的形式,并在*some\u id
指定节点和别名节点(而不是节点)之前插入
这与字符串级别上的替换不同,因为在解析YAML文件期间,可以保留引用。在Python中为集合类型上的任何锚加载YAML时,情况就是这样(即,在标量上使用锚时,not):
这将输出:
sub: &sub0 [a, X, c]
command:
params:
cmd1:
type: string
# Get the list defined in 'sub'
enum: *sub0
description: Exclude commands from the test list.
cmd2:
type: string
# Get the list defined in 'sub'
enum: *sub0
请注意,原始锚点名称保留在中
如果您不想在输出中使用锚点和别名,可以在RoundTripDumper
的RoundTripRepresenter
子类中重写ignore_alias
方法(该方法需要两个参数,但使用lambda*args:..
您不必知道):
其中:
sub: [a, X, c]
command:
params:
cmd1:
type: string
# Get the list defined in 'sub'
enum: [a, X, c]
description: Exclude commands from the test list.
cmd2:
type: string
# Get the list defined in 'sub'
enum: [a, X, c]
这个技巧可以用来读取YAML文件,就像你做了字符串替换一样,通过重新读取你转储的材料而忽略别名:
data2 = yaml.load(yaml.dump(yaml.load(yaml_str, Loader=yaml.RoundTripLoader),
Dumper=dumper, indent=4), Loader=yaml.RoundTripLoader)
# these are lists with the same value
assert data2['sub'] == data2['command']['params']['cmd1']['enum']
# but the loaded elements do not point to the same list
assert data2['sub'] is not data2['command']['params']['cmd1']['enum']
data2['command']['params']['cmd2']['enum'][5] = 'X'
yaml.dump(data2, sys.stdout, Dumper=yaml.RoundTripDumper, indent=4)
现在只有一个'b'
变成了'X'
:
sub: [a, b, c]
command:
params:
cmd1:
type: string
# Get the list defined in 'sub'
enum: [a, b, c]
description: Exclude commands from the test list.
cmd2:
type: string
# Get the list defined in 'sub'
enum: [a, X, c]
如上所述,仅当在集合类型上使用锚定/别名时,而不是在标量上使用锚定/别名时,才需要这样做
由于YAML可以创建对象,因此有可能影响 如果创建了这些对象,则将使用解析器。描述如何执行此操作。
²保留名称最初不可用,但在ruamel.yaml的更新中实现。请看:我更改了您的yaml代码,因为它在
b
之后的序列sub
中遗漏了一个引号。请注意,这些引号是多余的,我在回答中使用您的输入时遗漏了它们。另请参阅:
data2 = yaml.load(yaml.dump(yaml.load(yaml_str, Loader=yaml.RoundTripLoader),
Dumper=dumper, indent=4), Loader=yaml.RoundTripLoader)
# these are lists with the same value
assert data2['sub'] == data2['command']['params']['cmd1']['enum']
# but the loaded elements do not point to the same list
assert data2['sub'] is not data2['command']['params']['cmd1']['enum']
data2['command']['params']['cmd2']['enum'][5] = 'X'
yaml.dump(data2, sys.stdout, Dumper=yaml.RoundTripDumper, indent=4)
sub: [a, b, c]
command:
params:
cmd1:
type: string
# Get the list defined in 'sub'
enum: [a, b, c]
description: Exclude commands from the test list.
cmd2:
type: string
# Get the list defined in 'sub'
enum: [a, X, c]