首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用ruamel.yaml将YAML转储到字符串(而不是流)的最佳方法

使用ruamel.yaml将YAML转储到字符串(而不是流)的最佳方法
EN

Stack Overflow用户
提问于 2017-12-03 03:05:17
回答 3查看 11.5K关注 0票数 15

在过去,我使用与some_fancy_printing_loggin_func(yaml.dump(...), ...)兼容的ruamel.yaml进行类似的操作,但是我希望将代码转换为使用最新的API,这样我就可以利用一些新的格式化设置。

但是,我讨厌我必须指定一个流到ruamel.yaml.YAML.dump() .我不希望它直接写入流;我只希望它将输出返回给调用者。我遗漏了什么?

PS:我知道我可以做一些类似的事情,虽然我当然想避免这样做。

代码语言:javascript
运行
复制
f = io.StringIO()
yml.dump(myobj, f)
f.seek(0)
my_logging_func(f.read())
EN

Stack Overflow用户

发布于 2020-07-30 19:18:32

这个答案(ruamel.yaml的一个小包装器),在我经常需要这个功能之后,被我放入了一个pip模块中。

TLDR

pip install ez_yaml

代码语言:javascript
运行
复制
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 /复制粘贴解决方案

代码语言:javascript
运行
复制
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

原始答案(如果您想更多地自定义配置/选项)

代码语言:javascript
运行
复制
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解决了原来的“我只想让它把输出返回给调用者”,并呼吁Anthon的帖子没有回答这个问题。我将做进一步的工作: Anthon,您的模块很棒;往返旅行是令人印象深刻的,也是为数不多的几个模块之一。但是,(这经常发生在堆栈溢出上)使其他人的代码运行时高效并不是作者的工作。明确的权衡是伟大的,作者应该帮助人们理解他们的选择的后果。添加警告,包括名称中的“慢速”等,可能会非常有用。但是,ruamel.yaml文档中的方法;创建整个继承的类,并不是“显式”的。它们是封闭和混淆的,使得其他人很难执行,也很难理解这些附加代码存在的原因和原因。

许多用户完全不关心运行时的性能。没有YAML的我的程序运行时间是2周。一个500,000行yaml文件在几秒钟内被读取。两个星期和几秒钟都与项目无关,因为它们是CPU时间,项目是纯人工时间计费的。

由于在YAML上执行其他操作,YAML代码已经是一个字符串对象。强迫它进入流实际上会造成更多的开销。消除对YAML字符串形式的需求需要重写几个主要库,并可能需要几个月的努力;在这种情况下,流是一个非常不切实际的选择。

假设将其保持为流甚至是可能的,并且该项目是按CPU时间而不是人工时间计费的;优化50万行yaml文件字符串将提高≤0.0001%的效率。找出这个问题的答案所花费的额外时间,以及其他人花在理解这项工作上的时间,本来可以花在提高c-函数的效率上,这种c-函数每秒被调用100次。因此,即使我们确实关心CPU时间,特定的方法仍然不能成为一个有用的选择。

一篇文章忽略了这个问题,同时也暗示用户可能会花费大量的时间重写他们的应用程序,但这并不是一个答案。尊重别人,假设他们通常知道自己在做什么,并且知道其他选择。然后,提供可能更有效的方法将受到赞赏,而不是被拒绝。

末端咆哮

票数 11
EN
查看全部 3 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47614862

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档