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

Python yaml在引号中生成很少的值,python,python-2.7,yaml,pyyaml,Python,Python 2.7,Yaml,Pyyaml,我正在使用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',

我正在使用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)
输出:

hello: world
hostname: '"testhost"'
instance_type: test
my_list:
  - bar: test2
    foo: test
  - bar: test4
    foo: test3
name: foo
在上面的输出主机名值中有单引号和双引号,我只需要双引号

预期产出:

hello: world
hostname: "testhost"
instance_type: test
my_list:
  - bar: test2
    foo: test
  - bar: test4
    foo: test3
name: foo

您将获得双引号,因为这是您的输入数据。这一行:

'hostname': "\"testhost\"",

表示您希望
hosthame
具有一个以
开头和结尾的10个字符的字符串作为值,这就是您在yaml中看到的内容。此字符串带有转义双引号
“\“testhost\”
和yaml版本的
”testhost“
是同一数据的两种不同源代码表示形式。如果要在yaml中嵌入特殊字符(如新行的
\n
),只需在字符串周围加上双引号即可。但是
yaml.dump()
将为您解决这个问题。

您不能像这样引用部分数据来强制在yaml中引用。作为 引号强制转储程序对标量应用引号(即,不能再引用) 与yaml文件中的其他字符串值一样,使用普通标量)

您需要创建一个使用引号转储的类型。很容易 使用
ruamel.yaml
(免责声明:我是该文件的作者 PyYAML的增强版,支持yaml1.2,支持往返 保留评论和引用等)

其中:

instance_type: test
hostname: "testhost"
name: foo
my_list:
  - foo: test
    bar: test2
  - foo: test3
    bar: test4
hello: world
您还可以轻松加载该输出并将其转储,生成完全相同的输出:

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)

如果您坚持通过PyYAML执行此操作,您可以声明自己的强制报价类型并添加其representer:

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))
这将给你:

hello: world hostname: "testhost" instance_type: test my_list: - bar: test2 foo: test - bar: test4 foo: test3 name: foo 你好:世界 主机名:“testhost” 实例类型:test 我的清单: -酒吧:test2 foo:测试 -条形图:test4 foo:test3 姓名:富
免责声明:如果有选择,我也更愿意使用的模块来满足我的YAML需求。

这是一种非常奇怪的说法,YAML中的普通标量不能以双引号开头,因此被引用(这就是YAML标准指出的原因)。您也没有提供获取OP想要的输出的方法(即使不需要引号)。我试图向OP解释,他可能不需要以他看起来的方式指导
yaml.dump()
。而且也没有使用yaml特定的术语,他可能非常不理解。当然,他需要这样:“我只需要双引号”。您可以确定OP已经知道如何在给定的示例中不获取引号 hello: world hostname: "testhost" instance_type: test my_list: - bar: test2 foo: test - bar: test4 foo: test3 name: foo