gpt4 book ai didi

python-3.x - 使用 ruamel.yaml 将 YAML 转储到字符串的最佳方法(不流式传输)

转载 作者:行者123 更新时间:2023-12-03 23:50:48 26 4
gpt4 key购买 nike

过去,我做过类似 some_fancy_printing_loggin_func(yaml.dump(...), ...) ,使用 ruamel.yaml 的向后兼容部分,但我想将我的代码转换为使用最新的 API,以便我可以利用一些新的格式设置。
但是,我讨厌我必须为 ruamel.yaml.YAML.dump() 指定一个流。 ...我不希望它直接写入流;我只是想让它把输出返回给调用者。我错过了什么?
PS:我知道我可以做类似以下的事情,虽然我当然试图避免它。

f = io.StringIO()
yml.dump(myobj, f)
f.seek(0)
my_logging_func(f.read())

最佳答案

这个答案( ruamel.yaml 的一个小包装)被放入了 pip module here在如此频繁地需要此功能之后由我
TLDRpip install ez_yaml

import ez_yaml

ez_yaml.to_string(obj=your_object , options={})

ez_yaml.to_object(file_path=your_path, options={})
ez_yaml.to_object(string=your_string , options={})

ez_yaml.to_file(your_object, file_path=your_path)
原始问题的Hacky/复制粘贴解决方案
def object_to_yaml_str(obj, options=None):
#
# setup yaml part (customize this, probably move it outside this def)
#
import ruamel.yaml
yaml = ruamel.yaml.YAML()
yaml.version = (1, 2)
yaml.indent(mapping=3, sequence=2, offset=0)
yaml.allow_duplicate_keys = True
# show null
def my_represent_none(self, data):
return self.represent_scalar(u'tag:yaml.org,2002:null', u'null')
yaml.representer.add_representer(type(None), my_represent_none)

#
# the to-string part
#
if options == None: options = {}
from io import StringIO
string_stream = StringIO()
yaml.dump(obj, string_stream, **options)
output_str = string_stream.getvalue()
string_stream.close()
return output_str
原始答案(如果您想更多地自定义配置/选项)
import ruamel.yaml
from io import StringIO
from pathlib import Path

# setup loader (basically options)
yaml = ruamel.yaml.YAML()
yaml.version = (1, 2)
yaml.indent(mapping=3, sequence=2, offset=0)
yaml.allow_duplicate_keys = True
yaml.explicit_start = False
# show null
def my_represent_none(self, data):
return self.represent_scalar(u'tag:yaml.org,2002:null', u'null')
yaml.representer.add_representer(type(None), my_represent_none)

# o->s
def object_to_yaml_str(obj, options=None):
if options == None: options = {}
string_stream = StringIO()
yaml.dump(obj, string_stream, **options)
output_str = string_stream.getvalue()
string_stream.close()
return output_str

# s->o
def yaml_string_to_object(string, options=None):
if options == None: options = {}
return yaml.load(string, **options)

# f->o
def yaml_file_to_object(file_path, options=None):
if options == None: options = {}
as_path_object = Path(file_path)
return yaml.load(as_path_object, **options)

# o->f
def object_to_yaml_file(obj, file_path, options=None):
if options == None: options = {}
as_path_object = Path(Path(file_path))
with as_path_object.open('w') as output_file:
return yaml.dump(obj, output_file, **options)

#
# string examples
#
yaml_string = object_to_yaml_str({ (1,2): "hi" })
print("yaml string:", yaml_string)
obj = yaml_string_to_object(yaml_string)
print("obj from string:", obj)

#
# file examples
#
obj = yaml_file_to_object("./thingy.yaml")
print("obj from file:", obj)
object_to_yaml_file(obj, file_path="./thingy2.yaml")
print("saved that to a file")
咆哮
我感谢 Mike Night 解决了原来的“我只是希望它把输出返回给调用者”,并指出 Anthon 的帖子未能回答这个问题。我将进一步做:Anthon 你的模块很棒;往返令人印象深刻,是有史以来为数不多的旅行之一。但是,(这在 Stack Overflow 上经常发生)作者的工作不是让其他人的代码运行时高效。明确的权衡很好,作者应该帮助人们理解他们选择的后果。添加警告,包括名称中的“慢”等可能非常有帮助。但是,ruamel.yaml 文档中的方法;创建一个完整的继承类,不是“显式”的。它们是阻碍和混淆的,使得其他人难以执行并且耗费时间来理解额外代码存在的内容和原因。
许多用户理所当然地不关心运行时性能。我的程序的运行时间(没有 YAML)是 2 周。一个 500,000 行的 yaml 文件在几秒钟内被读取。 2 周和几秒钟都与项目无关,因为它们是 CPU 时间,项目纯粹按工时计费。
由于正在对其执行其他操作,YAML 代码已经是一个字符串对象。将其强制转换为流实际上会导致更多开销。消除对 YAML 字符串形式的需求将涉及重写几个主要库并可能需要数月的努力;在这种情况下,使流成为非常不切实际的选择。
假设将其保留为流甚至是可能的,并且该项目按 CPU 时间而不是工时计费;优化 500,000 行的 yaml 文件作为字符串将提高 ≤0.0001% 的效率。花在找出这个问题的答案上的额外时间,以及其他人理解解决方法所花的时间,本可以花在提高其中一个每秒被调用 100 次的 c 函数的效率上。因此,即使我们确实关心 CPU 时间,特定方法仍然不是一个有用的选择。
忽略这个问题同时还建议用户花费大量时间重写他们的应用程序的帖子不是答案。尊重他人,假设他们通常知道自己在做什么并且知道替代方案。然后,提供可能更有效的方法将得到赞赏而不是拒绝。
[结束吐槽]

关于python-3.x - 使用 ruamel.yaml 将 YAML 转储到字符串的最佳方法(不流式传输),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47614862/

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