简体   繁体   中英

Reading values from python object loaded from yaml file

I have a script that reads a YAML file into a python dictionary. How do I read the values and concatenate some of them to be more meaningful?

#script to load the yaml file into a python object
import yaml
from yaml import load, dump
#read data from the config yaml file
with open("config.yaml", "r") as stream:
    try:
        print(yaml.load(stream))
    except yaml.YAMLError as exc:
        print(exc)

Contents of YAML file:

os2:
  host:hostname
  ip:10.123.3.182
  path:/var/log/syslog
  file:syslog

Your yaml is inappropriately formatted. There should be a space after the : in each of the sub items like so:

os2:
    host: hostname
    ip: 10.123.3.182
    path: /var/log/syslog
    file: syslog

After that if you do a data = yaml.load(stream) it should pass the data correctly as such:

{'os2': {'file': 'syslog',
         'host': 'hostname',
         'ip': '10.123.3.182',
         'path': '/var/log/syslog'}}

Also, you don't need the line from yaml import load, dump since you already import yaml in its entirety.

Once the data is loaded, you can do pretty much anything you wish with it. You might want to use str.format() or f strings (Python 3.6+) as such:

'{host}@{ip}:{path}'.format(**data['os2'])

# 'hostname@10.123.3.182:/var/log/syslog'

this is called string formatting . The **data['os2'] bit is essentially unpacking the dictionary within `data['os2'] so you can refer to the keys directly in your string as such:

{'file': 'syslog',
 'host': 'hostname',
 'ip': '10.123.3.182',
 'path': '/var/log/syslog'}

Note that since your yaml doesn't include the key or value "ubuntu" there's no way for you to get reference that string unless you update your yaml .

Also Note: Don't confuse dictionary keys with attributes. You cannot reference data.os2.file as no such attribute exist under dictionary. You can however reference data['os2']['file'] (note they are in strings) to retrieve the data stored.

Your YAML is perfectly normal, and it loads as you can see here .

You have one key ( os2 ) and as value, a multiline plain scalar that loads, following the YAML standard, as a string with a space where the YAML has newline+spaces. That value thus loads as "host:hostname ip:10.123.3.182 path:/var/log/syslog file:syslog" .

Since you indicate you expect values (multiple), you either have to introduce make the value for os2 a flow-style mapping (in which case you must quote the scalars, otherwise you could eg not write plain URLs as scalars in valid YAML):

os2: {
  "host":"hostname",
  "ip":"10.123.3.182",
  "path":"/var/log/syslog",
  "file":"syslog"
  }

or you should follow the guideline from the YAML standard that

Normally, YAML insists the “:” mapping value indicator be separated from the value by white space.

os2:
  host: hostname
  ip: 10.123.3.182
  path: /var/log/syslog
  file: syslog

You should load YAML (when using PyYAML), using yaml.safe_load() as there is absolutely no need to use yaml.load() function, which is documented to be potentially unsafe.

With either of the above in config.yaml , you can do:

import sys
import yaml

with open('config.yaml') as stream:
    d = yaml.safe_load(stream)

os2 = d['os2']
# "concatenate" host, ip and path
print('{host}@{ip}:{path}'.format(**d['os2']))

to get:

hostname@10.123.3.182:/var/log/syslog

Your yaml file is incorrectly configured. There should be a space between each key and its value. You should have something like:

os2:
  host: hostname
  ip: 10.123.3.182
  path: /var/log/syslog
  file: syslog

yaml.load will return a dictionary whose values you can access normally.

{'os2': {'host': 'hostname', 'ip': '10.123.3.182', 'path': '/var/log/syslog', 'file': 'syslog'}}

Your code will look like this

#script to load the yaml file into a python object
import yaml
from yaml import load, dump
#read data from the config yaml file
with open("config.yaml", "r") as stream:
    try:
        config = yaml.load(stream)
        #concatenate into string
        string = f"{config['os2']['host']}@{config['os2']['ip']}:{config['os2']['path']}"
    except yaml.YAMLError as exc:
        print(exc)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM