首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PyYAML转储格式

PyYAML转储格式
EN

Stack Overflow用户
提问于 2013-12-27 17:54:05
回答 3查看 93.8K关注 0票数 54

我知道在StackOverflow上有一些关于这个的问题,但是我找不到我想要的东西。

我使用皮亚姆读取(.load())一个.yml文件,修改或添加一个密钥,然后再次写入(.dump())。问题是,我想保持文件格式后转储,但它改变了。

例如,我编辑键en.test.index.few来表示"Bye",而不是"Hello"

Python:

代码语言:javascript
复制
with open(path, "r", encoding = "utf-8") as yaml_file:
    self.dict = yaml.load(yaml_file)

然后,在更改密钥之后:

代码语言:javascript
复制
with open(path, "w", encoding = "utf-8") as yaml_file:
    dump = pyyaml.dump(self.dict, default_flow_style = False, allow_unicode = True, encoding = None)
    yaml_file.write( dump )

Yaml:

在此之前:

代码语言:javascript
复制
en:
  test:
    new: "Bye"
    index:
      few: "Hello"
  anothertest: "Something"

之后:

代码语言:javascript
复制
en:
  anothertest: Something
  test:
    index:
      few: Hello
    new: Bye

有办法保持相同的格式吗?例如,qoutes和order。我是不是用错了这个工具?

我知道,也许原始文件并不完全正确,但我无法控制它(它是Rails i18n文件)。

非常感谢。

EN

回答 3

Stack Overflow用户

发布于 2016-04-21 05:32:18

下面使用的是ruamel.yaml

ruamel.yaml积极维护。与PyYAML不同,ruamel.yaml支持:

  • YAML <= 1.2. PyYAML只支持YAML <= 1.1。这是至关重要的,因为YAML 1.2故意使用YAML 1.1在几种边缘情况下使用破坏向后兼容性。这通常是件坏事。在本例中,这使YAML 1.2成为JSON的严格超集。因为YAML 1.1不是JSON的严格超集,所以这是一件好事。
  • 往返保存.在调用yaml.dump()以转储先前调用yaml.load():加载的字典时
    • PyYAML天真地忽略了所有输入格式--包括注释、排序、引用和空格。丢弃像那么多的数字垃圾到最近的可用比特桶。
    • ruamel.yaml聪明地尊重所有输入格式。所有的一切。整个风格。整个文学作品。All.

图书馆迁移

在现有应用程序中,从PyYAML切换到ruamel.yaml通常只需将库导入更改为:

代码语言:javascript
复制
from ruamel import yaml

这是因为ruamel.yaml是一个符合PyYAML API的PyYAML叉。

不需要进行其他修改。yaml.load()yaml.dump()函数应该继续按预期运行。

往返机票保藏及对您有什么帮助

为了与PyYaml向后兼容,默认情况下,yaml.load()yaml.dump()函数不执行往返保留。为此,显式传递:

  • 可选的Loader=ruamel.yaml.RoundTripLoader关键字参数到yaml.load()
  • 可选的Dumper=ruamel.yaml.RoundTripDumper关键字参数到yaml.dump()

一个好心的“借用”文档的例子

代码语言:javascript
复制
import ruamel.yaml

inp = """\
# example
name:
  # Yet another Great Duke of Hell. He's not so bad, really.
  family: TheMighty
  given: Ashtaroth
"""

code = ruamel.yaml.load(inp, Loader=ruamel.yaml.RoundTripLoader)
code['name']['given'] = 'Astarte'  # Oh no you didn't.

print(ruamel.yaml.dump(code, Dumper=ruamel.yaml.RoundTripDumper), end='')

它完成了。注释、排序、引用和空格现在将保持原样。

票数 105
EN

Stack Overflow用户

发布于 2016-10-14 13:44:23

在我的示例中,如果"值包含{},则不需要任何内容。例如:

代码语言:javascript
复制
 en:
   key1: value is 1
   key2: 'value is {1}'

为此,请将函数represent_str()从模块PyYaml中的文件representer.py中复制,如果字符串包含{},则使用另一种样式。

代码语言:javascript
复制
def represent_str(self, data):
    tag = None
    style = None
    # Add these two lines:
    if '{' in data or '}' in data:
        style = '"'
    try:
        data = unicode(data, 'ascii')
        tag = u'tag:yaml.org,2002:str'
    except UnicodeDecodeError:
        try:
            data = unicode(data, 'utf-8')
            tag = u'tag:yaml.org,2002:str'
        except UnicodeDecodeError:
            data = data.encode('base64')
            tag = u'tag:yaml.org,2002:binary'
            style = '|'
    return self.represent_scalar(tag, data, style=style)

要在代码中使用它:

代码语言:javascript
复制
import yaml

def represent_str(self, data):
  ...

yaml.add_representer(str, represent_str)

在这种情况下,键和值之间没有差别,这对我来说就足够了。如果您希望对键和值使用不同的样式,则使用函数represent_mapping执行相同的操作。

票数 5
EN

Stack Overflow用户

发布于 2014-02-19 12:26:54

First

要表示字典数据,请使用以下代码:

代码语言:javascript
复制
mapping = list(mapping.items())
    try:
        mapping = sorted(mapping)
    except TypeError:
        pass

这就是为什么要改变顺序。

第二

在阅读时丢失关于标量类型(带双引号或不带双引号)的信息(这是库的主要方法)。

摘要

您可以根据'Dumper‘和重载方法'represent_mapping’创建自己的类,以更改字典的显示方式

要为标量保存有关双引号的信息,还必须基于“Loader”创建自己的类,但我担心它会影响和其他类,而且很难做到。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20805418

复制
相关文章

相似问题

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