【问题标题】:How to dump a folded scalar to YAML in Python (using ruamel?)如何在 Python 中将折叠的标量转储到 YAML(使用 ruamel?)
【发布时间】:2016-05-27 19:23:02
【问题描述】:

我一直在搜索 stackoverflow,寻找一种使用 Python 以 YAML 格式转储折叠标量的方法。一个常见的answer 来自用户Anthon,他建议使用他的ruamel Python 库。我接受了建议,但我不知道如何以折叠样式转储长 Python 字符串值。

在 Anthon 的回答中,他/她经常使用带有折叠样式表示器“>”的硬编码字符串来说明他的观点,如下所示:

yaml_str = """\
long: >
  Line1
  Line2
  Line3
"""
data = yaml.load(yaml_str, Loader=yaml.RoundTripLoader)
print(yaml.dump(data, Dumper=yaml.RoundTripDumper))

我不确定如何将该示例转换为我自己的代码,其中我要转储的字符串值不是来自已包含折叠表示器的硬编码值,而是来自 Django 请求(嗯它可能真的来自任何地方,关键是,我没有在我的代码中手动使用“>”构建字符串。

我真的打算这样做吗:

stringToDumpFolded = "ljasdfl\n\nksajdf\r\n;lak'''sjf"

data = "Key: > \n" + stringToDumpFolded

ruamel.yaml.dump(data, f, Dumper=yaml.RoundTripDumper))

否则,给定一个长的 unicode 字符串变量,我如何使用 ruamel 将其转储到文件中?

【问题讨论】:

  • 为什么字符串需要折叠?即使yaml.dump 输出它未折叠,它仍然是有效的 YAML。
  • 使用我在答案中名为 stringToDumpFolded 的示例字符串,我使用常规 pyyaml 将其转储到磁盘,它显示在文件中,如下所示:{key: "ljasdfl\n\nksajdf\r\n;lak'''sjf"} 当我尝试重新加载文件时使用 yaml.load() 进入 yaml,我得到一个很长的 list 错误。
  • 这似乎是XY problem。您的问题是“如何将折叠的标量转储到 YAML”,但您要解决的实际问题似乎是您的评论中提到的错误。

标签: python yaml


【解决方案1】:

从 0.15.61 开始,可以在 ruamel.yaml 中往返折叠标量:

import sys
import ruamel.yaml

yaml_str = """\
long: >
  Line1
  Line2
  Line3
"""

yaml = ruamel.yaml.YAML()
data = yaml.load(yaml_str)
print(type(data['long']), data['long'].fold_pos, end='\n-----\n')
yaml.dump(data, sys.stdout)

给出:

<class 'ruamel.yaml.scalarstring.FoldedScalarString'> [5, 11]
-----
long: >
  Line1
  Line2
  Line3

类型的印刷品仅用于显示您如何建立 如果从头开始工作,您自己要创建什么对象:

from ruamel.yaml.scalarstring import FoldedScalarString as folded

s = folded('Line1 Line2 Line3\n')
data = dict(long=s)
yaml.dump(data, sys.stdout)

它给出了一个折叠的标量,但可能不是你想要的方式:

long: >
  Line1 Line2 Line3

要让这个折叠你必须提供.fold_pos 属性。那 属性必须是一个列表(或一些可逆的可迭代),的位置 字符串中的空格字符,其中需要插入折叠:

s = folded('Line1 Line2 Line3\n')
s.fold_pos = [5, 11]
data = dict(long=s)
yaml.dump(data, sys.stdout)

返回你期望的输出:

long: >
  Line1
  Line2
  Line3

由于您似乎希望所有空格都被折叠,您还可以执行以下操作:

import re
s.fold_pos = [x.start() for x in re.finditer(' ', s)]

【讨论】:

    猜你喜欢
    • 2021-12-17
    • 1970-01-01
    • 2021-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-02
    • 2020-05-23
    • 2019-04-16
    相关资源
    最近更新 更多