【问题标题】:Python YAML hiera and how have value be inside double quotes?Python YAML hiera 以及双引号内的值如何?
【发布时间】:2017-03-24 03:38:38
【问题描述】:

我有这个代码

python_data_struct = {
        'amazon_app_id': amazon_app_id,
        'librivox_rest_url': librivox_rest_url,
        'librivox_id': librivox_id,
        'top': top,
        'pacakge': 'junk',
        'version': 'junk',
        'password': password,
        'description': description,
        'long_description': long_description,
        'make_audiobook::sftp_script::appname': '\"%{::appname}\"'
}
try:
        myyaml = yaml.dump(python_data_struct)
except:
        e = sys.exc_info()[0]
        print "Error on %s Error [%s]" % ( librivox_rest_url, e )
        sys.exit(5)
write_file( myyaml, hiera_dir + '/' + appname + '.yaml' );

它输出如下所示的 yaml:

{amazon_app_id: junk, description: !!python/unicode ' Riley was an American writer
    known as the "Hoosier poet", and made a start writing newspaper verse in Hoosier
    dialect for the Indianapolis Journal in 1875. His favorite authors were Burns
    and Dickens. This collection of poems is a romanticized and mostly boy-centered
    paean to a 19th century rural American working-class childhood. (Summary by Val
    Grimm)', librivox_id: '1000', librivox_rest_url: 'https://librivox.org/api/feed/audiobooks/id/1000/extended/1/format/json',
  long_description: !!python/unicode "\n Riley was an American writer known as the\
    \ \"Hoosier poet\", and made a start writing newspaper verse in Hoosier dialect\
    \ for the Indianapolis Journal in 1875. His favorite authors were Burns and Dickens.\
    \ This collection of poems is a romanticized and mostly boy-centered paean to\
    \ a 19th century rural American working-class childhood. (Summary by Val Grimm)\n\
    \nThe \"Selected Riley Child-Rhymes\" App will not use up your data plan's minutes\
    \ by downloading the audio files (mp3) over and over. You will download load all\
    \ the data when you install the App. The \"Selected Riley Child-Rhymes\" App works\
    \ even in airplane mode and in places without Wi-Fi or phone network access! So\
    \ you can listen to your audio book anywhere anytime! The \"Selected Riley Child-Rhymes\"\
    \ App automatically pauses when you make or receive a phone call and automatically\
    \ resumes after the call ends. The \"Selected Riley Child-Rhymes\" App will continue\
    \ to play until you exit the App or pause the reading so it is perfect for listening\
    \ in bed, at the gym, or while driving into work.\" \n", 'make_audiobook::sftp_script::appname': '"%{::appname}"',
  pacakge: junk, password: junk, top: junk, version: junk}

很难看出,但有问题的特定键/值对是这个:

'make_audiobook::sftp_script::appname': '"%{::appname}"',

我需要它是这样的:

'make_audiobook::sftp_script::appname': "%{::appname}",

只是在%{::appname} 周围加上双引号我不知道在我的python 代码中要做什么。请帮忙:)

【问题讨论】:

    标签: python yaml hiera


    【解决方案1】:

    如果你想要一个 YAML 中的字符串,那么你只需要一个 Python 中的字符串:

    python_data_struct = {
        'make_audiobook::sftp_script::appname': '%{::appname}'
    }
    
    print yaml.dump(python_data_struct)
    

    这给了你:

    {'make_audiobook::sftp_script::appname': '%{::appname}'}
    

    或者等价的,default_flow_style=False:

    make_audiobook::sftp_script::appname: '%{::appname}'
    

    在 YAML 中 "a value" 使用双引号和 'a value' 使用单引号之间没有区别。这个:

    my_key: 'my value'
    

    还有这个:

    my_key: "my value"
    

    两者都将评估为完全相同的数据结构。

    【讨论】:

    • 当 hiera 使用 yaml 文件时不会。我计划将此 yaml 文件用作 puppet 类的分层数据。 "%{::appname}" 是 hiera 将评估的傀儡事实。 '%{::appname}' 是文字字符串。感谢您发布答案:)
    • @RedCricket 除非 hiera 实现自己的类似 YAML 的语法,否则这是不可能的。 "%{::appname}"'%{::appname}' 在 YAML 中是相同的东西,如果对这些值进行不同的处理,这违反了 YAML 规范,应该报告为错误。 docs 表示“在 YAML 文件中,任何包含插值标记的字符串都必须被引用。”。他们没有说双引号
    • 我自己使用hiera,我可以确认这只是 YAML。单引号,双引号都没关系。
    • 确实是这样,但这对我来说似乎很麻烦。如何让 hiera 评估文字 %{::puppet_fact_foo} 的任何内容?但这是另一个问题。
    【解决方案2】:

    如果您需要控制 Python YAML 转储中的引号,我建议使用 ruamel.yaml(免责声明:我是该软件包的作者)

    import sys
    from ruamel import yaml
    
    amazon_app_id = 'junk'
    librivox_rest_url = 'https://librivox.org/api/feed/audiobooks/id/1000/extended/1/format/json'
    
    python_data_struct = {
            'amazon_app_id': amazon_app_id,
            'librivox_rest_url': librivox_rest_url,
            'pacakge': 'junk',
            'version': 'junk',
            yaml.scalarstring.SingleQuotedScalarString('make_audiobook::sftp_script::appname'):
                yaml.scalarstring.DoubleQuotedScalarString('%{::appname}')
    }
    
    try:
        with open(hiera_dir + '/' + appname + '.yaml') as fp:
            yaml.round_trip_dump(python_data_struct, fp)
    except Exception as e:
        print("Error on {} Error [{}]".format(librivox_rest_url, e))
        sys.exit(5)
    

    给你:

    librivox_rest_url: https://librivox.org/api/feed/audiobooks/id/1000/extended/1/format/json
    version: junk
    'make_audiobook::sftp_script::appname': "%{::appname}"
    amazon_app_id: junk
    pacakge: junk
    

    请注意,默认情况下,PyYAML 会在嵌入了“:”的标量周围加上引号,即使该字符后面没有空格,尽管这不是必需的。

    round_trip_dump()也没有使用第二个参数,(dump()也有这个参数)。不提供该参数并让 YAML 文件先在内存中构建是非常低效的。

    我还更改了您的一些其他代码,除非您被困在 Python 2.6 左右,否则您应该 IMO 现代化您的语法。您可能还想查看键名(您的意思是“pacakge”吗?)

    【讨论】:

    • 如果 OP 需要在生成的 YAML 中控制引号,那就大错特错了。
    • @larsks 我同意,但如果 OP 无法控制 YAML 的使用,唯一要做的就是尝试遵守。
    猜你喜欢
    • 1970-01-01
    • 2018-11-20
    • 2021-06-02
    • 2019-05-05
    • 1970-01-01
    • 2019-02-15
    • 2022-11-17
    • 2011-04-19
    相关资源
    最近更新 更多