如何在转储 yaml 时保留键值中的缩进



转储yaml时如何保留键值中的缩进?我正在使用鲁阿梅尔山药

法典:

in_str='''Pets:
Cat:
Tom
Mouse:
Jerry
Dog:
Scooby
'''

import ruamel.yaml, sys
results = ruamel.yaml.load(in_str, ruamel.yaml.RoundTripLoader, preserve_quotes=True)
results['Pets']['Bird']='Tweety'
ruamel.yaml.dump(results, sys.stdout, ruamel.yaml.RoundTripDumper, default_flow_style=True,indent=2, block_seq_indent=2)

输出:

Pets:
Cat: Tom
Mouse: Jerry
Dog: Scooby
Bird: Tweety

预期输出:

Pets:
Cat:
Tom
Mouse:
Jerry
Dog:
Scooby
Bird:
Tweety

为了实现这一点,你必须挂接到Emitter,让它在处理映射值时插入换行符和适当的缩进。这可以使用您使用的旧样式 API 来完成,但最好使用新的 ruamel.yaml API 来完成,例如,它为您提供了缩进具有不同值的序列和映射的可能性:

import sys
import ruamel.yaml
from ruamel.yaml.emitter import Emitter
class MyEmitter(Emitter):
def expect_block_mapping_simple_value(self):
# type: () -> None
if getattr(self.event, 'style', None) != '?':
# prefix = u''
if self.indent == 0 and self.top_level_colon_align is not None:
# write non-prefixed colon
c = u' ' * (self.top_level_colon_align - self.column) + self.colon
else:
c = self.prefixed_colon
self.write_indicator(c, False)
# the next four lines force a line break and proper indent of the value
self.write_line_break()
self.indent += self.best_map_indent
self.write_indent()
self.indent -= self.best_map_indent
self.states.append(self.expect_block_mapping_key)
self.expect_node(mapping=True)

in_str='''
Pets:
Cat:
Tom
Mouse:
- Jerry
- 'Mickey'
Dog:
Scooby
'''
yaml = ruamel.yaml.YAML()
yaml.Emitter = MyEmitter
yaml.indent(mapping=4, sequence=2, offset=0)
yaml.preserve_quotes = True
results = yaml.load(in_str)
results['Pets']['Bird']='Tweety'
yaml.dump(results, sys.stdout)

这给出了:

Pets:
Cat:
Tom
Mouse:
- Jerry
- 'Mickey'
Dog:
Scooby
Bird:
Tweety

注意事项:

  • 您只需要处理简单的标量值(与映射/序列相反,它们已经在块序列"模式"中"推送"到下一行)
  • 从源复制expect_block_mapping_simple_value并添加几行。目前没有"钩子"可以在不复制某些代码的情况下执行此操作。
  • 如果您有序列并且需要不同的缩进,则可以使用sequence值并offsetyaml.indent()值。
  • 所有这些都假设缩进一致,单个缩进不会被保留(即,如果某些值缩进的四个位置多于或小于四个位置,它们最终将得到 4 个位置)。

最新更新