gpt4 book ai didi

python - 在 PyYAML 中使用表示器时控制折叠位置

转载 作者:行者123 更新时间:2023-12-01 07:01:01 25 4
gpt4 key购买 nike

我可以使用以下代码以折叠形式转储包含长字符串的 YAML 代码:

import yaml

class folded_str(str): pass

def folded_str_representer(dumper, data):
return dumper.represent_scalar(u'tag:yaml.org,2002:str', data, style='>')

yaml.add_representer(folded_str, folded_str_representer)

data = {
'foo': folded_str(('abcdefghi ' * 10) + 'end\n'),
}

print(yaml.dump(data))

上述代码的输出是:

foo: >
abcdefghi abcdefghi abcdefghi abcdefghi abcdefghi abcdefghi abcdefghi abcdefghi
abcdefghi abcdefghi end

是否可以控制折叠发生后的长度?例如,如果我希望行在 70 个字符后折叠,那么输出将如下所示:

foo: >
abcdefghi abcdefghi abcdefghi abcdefghi abcdefghi abcdefghi abcdefghi
abcdefghi abcdefghi abcdefghi end

有没有办法让 PyYAML 做到这一点?

最佳答案

控制 PyYAML 输出的行长度的简单方法折叠,是通过参数 width 提供(全局)线长度:

import sys
import yaml

class folded_str(str): pass

def folded_str_representer(dumper, data):
return dumper.represent_scalar(u'tag:yaml.org,2002:str', data, style='>')

yaml.add_representer(folded_str, folded_str_representer)

data = {
'foo': folded_str(('abcdefghi ' * 10) + 'end\n'),
}

yaml.dump(data, sys.stdout, width=70)

给出:

foo: >
abcdefghi abcdefghi abcdefghi abcdefghi abcdefghi abcdefghi abcdefghi
abcdefghi abcdefghi abcdefghi end

如您所见,我删除了对 print 的调用。 PyYAML 有一个流式传输接口(interface)并且不直接流式传输到输出,它需要制作一个输出的内存解释既不必要地慢又占用内存低效。

当然,这也会影响任何其他被转储的行(长非折叠标量、流式列表、深度嵌套数据结构。

不容易的方法是不调用 represent_scalar 例程,并且适应 PyYAML 的 ScalarNode (或创建您自己的 Node 类型),然后在发出时在适当的位置输出换行符。

<小时/>

我的ruamel.yaml内置了此功能,以允许此类输出往返保留折叠位置(即使默认输出宽度相同作为 PyYAML 的)

import sys
import ruamel.yaml

yaml_str = """\
[long, scalar]: "This is just a filler to show that the default width is 80 chars"
foo: >
abcdefghi abcdefghi abcdefghi abcdefghi abcdefghi abcdefghi abcdefghi
abcdefghi abcdefghi abcdefghi end
"""

yaml = ruamel.yaml.YAML()
data = yaml.load(yaml_str)
yaml.dump(data, sys.stdout)

给出:

[long, scalar]: This is just a filler to show that the default width is 80 chars
foo: >
abcdefghi abcdefghi abcdefghi abcdefghi abcdefghi abcdefghi abcdefghi
abcdefghi abcdefghi abcdefghi end

尽管您可以从头开始创建这样的折叠字符串,但这并不简单(有没有 API,并且内部表示可能会改变)。我推荐的是只需创建折叠字符串数据,然后通过不同地定义 folded_str 来加载它:

import sys
import ruamel.yaml

yaml = ruamel.yaml.YAML()

def folded_str(s, pos=70):
parts = []
r = ""
for part in s.split(' '):
if not r:
r = part
elif len(r) + len(part) >= pos:
parts.append(r + '\n')
r = part
else:
r += ' ' + part
parts.append(r)
return yaml.load(">\n" + "".join(parts))

data = {
'foo': folded_str(('abcdefghi ' * 10) + 'end\n'),
}

yaml.dump(data, sys.stdout)

给出:

foo: >
abcdefghi abcdefghi abcdefghi abcdefghi abcdefghi abcdefghi abcdefghi
abcdefghi abcdefghi abcdefghi end

关于python - 在 PyYAML 中使用表示器时控制折叠位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58627817/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com