'Input YAML config values into keyword arguments for Python

I'd like to have a YAML config file for certain analysis settings for my Python script. The YAML file looks something like this:

settings:
  param1: 1
  param2: two
  ...

In my Python script, I want to pass these values as keyword arguments to a function. Loading in the YAML file gives me a dictionary. The function only has keyword arguments and I don't know beforehand which keyword arguments the config file will have. The function looks something like this:

def process(param1=None, param2=None, param3=None):
    ...

Note that the name of the YAML settings are the same as the keyword argument names. The function has several possible keyword arguments, and the config file may only have one or two. Obviously, I want to assign the values to the right keyword arguments.

How can I assign YAML values (and/or a dict) to their keyword argument assignments?



Solution 1:[1]

You can get the dictionary from yaml.load() and use the ** syntax to pass the key/values into a function. This way you don't have to know the keys beforehand. For example:

import yaml

with open('path/to/config.yml', 'rb') as f:
    conf = yaml.safe_load(f.read())    # load the config file

def process(**params):    # pass in variable numbers of args
    for key, value in params.items():
        print('%s: %s' % (key, value))

process(**conf)    # pass in your keyword args

Try this out with your code and it should give you enough insight into how to implement your own.

Solution 2:[2]

So, I ran across you question and I thought this might help. PyYAML is awesome! One of the things it supports is class mapping directly from python

import yaml
class Hero:
    def __init__(self, name, hp, sp):
        self.name = name
        self.hp = hp
        self.sp = sp
    def __repr__(self):
        return "Hero %s has %d Hitpoints" % (self.name, self.hp)


f = "sample.yml"
with open(f, mode='w') as ff:
    ff.write(yaml.dump(Hero(name="Cool Guy", hp=4, sp=10)))

    # saves as !!python/object:__main__.Hero {hp: 4, name: Cool Guy, sp: 10}

    ff.close()
with open(f, mode="r") as fx:
    y = yaml.load(fx)
    print(y)

[out]: Hero Cool Guy has 4 Hitpoints

Hope you find as much use out of this as I did. Check out the PyYAML Docs for more information.

Solution 3:[3]

You can iterate over the keys in the dict in python as:

for key in data:
    print(key)

That will allow you to grab the key and use it in your function by calling:

data[key] # returns value from dict

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Dan Temkin
Solution 3 Tux