【问题标题】:How can I print [] without string in Python in YAML file如何在 YAML 文件中在 Python 中打印不带字符串的 []
【发布时间】:2015-07-21 11:28:07
【问题描述】:

在我的 yam 文件中我正在尝试这个

with open(fname, "w") as f:
     yaml.safe_dump({'items':['test', 'test2']}, f,
                    default_flow_style=False, width=50, indent=4)

它以以下格式打印

items:
- 'test'
- 'test2'

我希望输出格式如下

items: ['test', 'test2']

我该怎么做?

编辑:

这是我的完整代码

   d = {}        
   for m in ['B1', 'B2', 'B3']:
                d2 = {}
                for f in ['A1', 'A2', 'A3']:
                    # here i don't want any flow style
                    d2[f] = ['test', 'test2']
                d[m] = d2

    with open(fname, "w") as f:
        yaml.safe_dump(d, f, default_flow_style=True, width=50, indent=8)

【问题讨论】:

  • 如果你想要默认的流样式,为什么要添加default_flow_style=False?
  • @abarnert 我有嵌套的 dict ,我不希望只有一个 dict 的默认流样式,而是我想要的其他。有没有可能
  • 你希望你的 YAML 文件中的所有列表都是流式的,还是只有特定的列表?

标签: python yaml pyyaml


【解决方案1】:

不要把default_flow_style=False然后,does the complete opposite of what you want:

>>> import yaml
>>> yaml.safe_dump({'items': ['test', 'test2']}, default_flow_style=False)
'items:\n- test\n- test2\n'
>>> yaml.safe_dump({'items': ['test', 'test2']})
'items: [test, test2]\n'

至于部分文档格式,可以自定义representers,例如:

class Items(list):
    pass


def items_representer(dumper, data):
    return dumper.represent_sequence('tag:yaml.org,2002:seq', data, flow_style=True)


yaml.representer.SafeRepresenter.add_representer(Items, items_representer)

result = yaml.safe_dump({
    'items': Items(['test', 'test2']),
    'other list': ['1', '2'],
}, default_flow_style=False)

# items: [test, test2]
# other list:
# - '1'
# - '2'
print(result)

【讨论】:

  • 我有嵌套的 dict ,我不希望只有一个 dict 的默认流样式,而是其他我想要的。有没有可能
【解决方案2】:

如果你想要精细控制并且只有流式风格的特定列表,你应该使用ruamel.yaml(这是我的PyYAML增强版):

import ruamel.yaml
from ruamel.yaml.comments import CommentedSeq

d = {}
for m in ['B1', 'B2', 'B3']:
    d2 = {}
    for f in ['A1', 'A2', 'A3']:
        # here i don't want any flow style
        d2[f] = CommentedSeq(['test', 'test2'])
        if f != 'A2':
            d2[f].fa.set_flow_style()
    d[m] = d2

x = ruamel.yaml.dump(
    d, Dumper=ruamel.yaml.RoundTripDumper,
    default_flow_style=False, width=50, indent=8)
print(x)

会给你:

B1:
        A1: [test, test2]
        A3: [test, test2]
        A2:
        - test
        - test2
B2:
        A1: [test, test2]
        A3: [test, test2]
        A2:
        - test
        - test2
B3:
        A1: [test, test2]
        A3: [test, test2]
        A2:
        - test
        - test2

CommentedSeq 的行为就像一个普通的 Python 列表,但允许您指定注释、设置流/块样式等。

ruamel.yaml 通常用于在往返 YAML 时保留 cmets、元素上的流/块样式等。 IE。如果你想追加:

d2 = ruamel.yaml.load(x, Loader=ruamel.yaml.RoundTripLoader)
y = ruamel.yaml.dump(
    d2, Dumper=ruamel.yaml.RoundTripDumper, width=50, indent=8)
assert x == y

断言成立。

但它当然也可以用于从头开始生成 YAML。你可以例如还可以使用 CommentedMap 类型并保持 dict/mapping 的键有序。

【讨论】:

  • @user3214546 为dump() 提供一个stream=fp 和fp 一个打开的文件指针(with open('somefile.yaml', 'w') as fp:)。如果stream 是None,则“转储”作为字符串返回。
  • 我正在使用你的图书馆。有什么办法可以在文件顶部添加评论,比如描述文件的目的是什么而不是用键
  • @user3214546 是的,因为如果您往返,文件 cmets 的开头将被保留。每条评论都是自己的一行,因此它永远不会只是替换一行。你能发布一个新问题,清楚地说明你从什么开始(顶部有注释的文件需要更改(如果是多少行),顶部没有注释的文件),需要插入什么(一个注释行,多个注释行)。如果您愿意,请在此处联系我,我会尽快回复。
  • 我在这里添加了问题stackoverflow.com/questions/30994370/…
  • 如果我使用CommentedSeq(["test"]) 那么输出是[test] 我怎样才能得到['test']的输出
猜你喜欢
  • 2023-01-09
  • 2020-03-01
  • 2018-06-13
  • 2011-10-17
  • 1970-01-01
  • 1970-01-01
  • 2010-10-05
  • 2014-12-14
  • 1970-01-01
相关资源
最近更新 更多