Python YAML hiera and how have value be inside double quotes?

核能气质少年 提交于 2019-12-12 04:35:24

问题


I have this code

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' );

It outputs yaml that looks like this:

{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}

It is hard to see but the particular key/value pair that is a problem is this one:

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

I need to it to be this:

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

Just double quotes around %{::appname} I cannot figure out what to do in my python code. Please help :)


回答1:


If you want a string in YAML, then you just need a string in Python:

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

print yaml.dump(python_data_struct)

Which gives you:

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

Or equivalently, with default_flow_style=False:

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

There is no different in YAML between "a value" using double quotes and 'a value' using single quotes. This:

my_key: 'my value'

And this:

my_key: "my value"

Will both evaluate to the exact same data structure.




回答2:


If you need to control quotes in your Python YAML dump, I recommend using ruamel.yaml (Disclaimer: I am the author of that package)

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)

which gives you:

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

Please note that PyYAML does by default put quotes around scalars that have a ':' embedded, even if that character is not followed by a space, although that is not necessary.

Also not the use of the second parameter to round_trip_dump(), (dump() has this parameter as well). It is highly inefficient to not provide that parameter and let the YAML file built-up in memory first.

I also changed some of your other code, unless you are stuck on Python 2.6 or so, you should IMO modernize your syntax. You might also want to look at the keynames (did your really mean 'pacakge'?)



来源:https://stackoverflow.com/questions/42990994/python-yaml-hiera-and-how-have-value-be-inside-double-quotes

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!