Python yaml 在引号中生成很少的值

Dev*_*nga 5 python yaml pyyaml python-2.7

我正在 Python 脚本中使用该yaml模块来生成 YAML 文件。下面是一个例子:

import yaml
class MyDumper(yaml.Dumper):

    def increase_indent(self, flow=False, indentless=False):
        return super(MyDumper, self).increase_indent(flow, False)

foo = {
    'instance_type': 'test',
    'hostname': "\"testhost\"",
    'name': 'foo',
    'my_list': [
        {'foo': 'test', 'bar': 'test2'},
        {'foo': 'test3', 'bar': 'test4'}],
    'hello': 'world',
}

print yaml.dump(foo, Dumper=MyDumper, default_flow_style=False)
Run Code Online (Sandbox Code Playgroud)

输出:

hello: world
hostname: '"testhost"'
instance_type: test
my_list:
  - bar: test2
    foo: test
  - bar: test4
    foo: test3
name: foo
Run Code Online (Sandbox Code Playgroud)

在上面的输出主机名值有单引号和双引号,我只想要双引号。

预期输出:

hello: world
hostname: "testhost"
instance_type: test
my_list:
  - bar: test2
    foo: test
  - bar: test4
    foo: test3
name: foo
Run Code Online (Sandbox Code Playgroud)

zwe*_*wer 6

如果您坚持通过 PyYAML 执行此操作,则可以声明自己的强制引用类型并添加其表示者:

import yaml

class MyDumper(yaml.Dumper):  # your force-indent dumper

    def increase_indent(self, flow=False, indentless=False):
        return super(MyDumper, self).increase_indent(flow, False)

class QuotedString(str):  # just subclass the built-in str
    pass

def quoted_scalar(dumper, data):  # a representer to force quotations on scalars
    return dumper.represent_scalar('tag:yaml.org,2002:str', data, style='"')

# add the QuotedString custom type with a forced quotation representer to your dumper
MyDumper.add_representer(QuotedString, quoted_scalar)

foo = {
    'instance_type': 'test',
    'hostname': QuotedString('testhost'),  # here's the 'magic'
    'name': 'foo',
    'my_list': [
        {'foo': 'test', 'bar': 'test2'},
        {'foo': 'test3', 'bar': 'test4'}],
    'hello': 'world',
}

print(yaml.dump(foo, Dumper=MyDumper, default_flow_style=False))
Run Code Online (Sandbox Code Playgroud)

这会给你:

你好世界
主机名:“测试主机”
实例类型:测试
我的列表:
  - 栏:测试2
    foo:测试
  - 栏:测试4
    foo:测试3
名称: 富

免责声明:如果可以选择,我也更喜欢Anthonruamel.yaml模块来满足我的 YAML 需求。


Ant*_*hon 4

您不能像以前那样通过引用部分数据来在 YAML 中强制引用。由于引号强制转储程序对标量应用引号(即不能再像 yaml 文件中的其他字符串值一样使用普通标量)。

您需要创建一个用引号转储的类型。最简单的方法是使用ruamel.yaml(免责声明:我是 PyYAML 增强版的作者,支持 YAML 1.2,支持注释和引用的往返保存等)。

import sys
import ruamel.yaml
from ruamel.yaml.scalarstring import DoubleQuotedScalarString as dq


yaml = ruamel.yaml.YAML()
yaml.indent(sequence=4, offset=2)

foo = {
    'instance_type': 'test',
    'hostname': dq("testhost"),
    'name': 'foo',
    'my_list': [
        {'foo': 'test', 'bar': 'test2'},
        {'foo': 'test3', 'bar': 'test4'}],
    'hello': 'world',
}


yaml.dump(foo, sys.stdout)
Run Code Online (Sandbox Code Playgroud)

这使:

instance_type: test
hostname: "testhost"
name: foo
my_list:
  - foo: test
    bar: test2
  - foo: test3
    bar: test4
hello: world
Run Code Online (Sandbox Code Playgroud)

您还可以轻松加载该输出并转储它,生成完全相同的输出:

from ruamel.yaml.compat import StringIO

buf = StringIO()
yaml.dump(foo, buf)

yaml.preserve_quotes = True
data = yaml.load(buf.getvalue())
yaml.dump(data, sys.stdout)
Run Code Online (Sandbox Code Playgroud)