Python uses PyYAML library to read and write yaml configuration files

Keywords: Programming Python encoding

I. yaml file introduction

yaml is a special language for writing configuration files.

1. yaml file rules

  • Case sensitive;
  • Use indents to represent hierarchical relationships;
  • Indent with spacebar instead of Tab
  • The number of indented spaces is not fixed, only the left side of elements of the same level needs to be aligned;
  • The strings in the file do not need to be marked with quotation marks, but if the strings contain special characters, they need to be marked with quotation marks;
  • Note identification is#

2. yaml file data structure

  • Object: set of key value pairs (referred to as "map or dictionary")
  • Key value pairs are represented by a colon ":" structure, and the colon and value are separated by spaces
  • Array: a set of ordered values (sequence or list for short)
  • The array is preceded by a "-" symbol, which is separated from the value by a space
  • Scalars: a single, indivisible value (such as string, bool value, integer, floating-point number, time, date, null, etc.)
  • The value of None can be represented by null ~

II. Reading yaml configuration file in python

1. Prerequisites

You need to install pyyaml and import yaml module before reading yaml file in python:

  • Pyyaml (pip3 install pyyaml) is the module to be installed when using yaml;
  • The imported module is yaml (import yaml)

2. Read yaml file data

python reads the file data through the open mode, and then converts the data into a list or dictionary through the load function;

import yaml
import os

def get_yaml_data(yaml_file):
    # Open yaml file
    print("***Obtain yaml file data***")
    file = open(yaml_file, 'r', encoding="utf-8")
    file_data = file.read()
    file.close()
    
    print(file_data)
    print("Type:", type(file_data))

    # Convert a string to a dictionary or list
    print("***conversion yaml Data is dictionary or list***")
    data = yaml.full_load(file_data)
    print(data)
    print("Type:", type(data))
    return data
current_path = os.path.abspath(".")
yaml_path = os.path.join(current_path, "config.yaml")
get_yaml_data(yaml_path)

"""
***Obtain yaml file data***
# yaml key value pair: dictionary in python
usr: my
psw: 123455
//Type: < class' STR '>
***conversion yaml Data is dictionary or list***
{'usr': 'my', 'psw': 123455}
//Type: < class' dict '>
"""

3. yaml file data is key value pair

(1) yaml file contains key value pairs:

# yaml key value pair: dictionary in python
usr: my
psw: 123455
s: " abc\n"

Data obtained by python after parsing yaml file:

{'usr': 'my', 'psw': 123455, 's': ' abc\n'}

(2) the content of yaml file is "key value pair 'nesting" key value pair "

# yaml key value pair nesting: Dictionary nesting dictionary in python
usr1:
  name: a
  psw: 123
usr2:
  name: b
  psw: 456

Data obtained by python after parsing yaml file:

{'usr1': {'name': 'a', 'psw': 123}, 'usr2': {'name': 'b', 'psw': 456}}

(3) nesting "array" in "key value pair" in yaml file

# Nested array in yaml key value pair
usr3:
  - a
  - b
  - c
usr4:
  - b

Data obtained by python after parsing yaml file:

{'usr3': ['a', 'b', 'c'], 'usr4': ['b']}

4. yaml file data is an array

(1) contents in yaml file are arrays

# yaml array
- a
- b
- 5

Data obtained by python after parsing yaml file:

['a', 'b', 5]

(2) nesting key value pairs in yaml file array

# Nested key value pairs in yaml array
- usr1: aaa
- psw1: 111
  usr2: bbb
  psw2: 222

Data obtained by python after parsing yaml file:

[{'usr1': 'aaa'}, {'psw1': 111, 'usr2': 'bbb', 'psw2': 222}]

5. Basic data types in yaml file:

# Scalar quantity
s_val: name              # String: {'s_val': 'name'}
spec_s_val: "name\n"    # Special string: {'spec_s_val': 'name\n'
num_val: 31.14          # Number: {'num_val': 31.14}
bol_val: true           # Boolean value: {'bol_val': True}
nul_val: null           # null value: {'nul_val': None}
nul_val1: ~             # null value: {'nul_val1': None}
time_val: 2018-03-01t11:33:22.55-06:00     # Time value (iso8601 format): {'time_val': datetime.datetime(2018, 3, 1, 17, 33, 22, 550000)}
date_val: 2019-01-10    # Date value: {'date_val': datetime.date(2019, 1, 10)}

6. Reference in yaml file

Content in yaml file

animal3: &animal3 fish
test: *animal3

Data read by python

{'animal3': 'fish', 'test': 'fish'}

III. reading multiple yaml documents in python

1. Multiple documents in a yaml file are segmented by the separation method

For example: data in yaml file

# Multiple documents in segmented yaml file
---
animal1: dog
age: 2
---
animal2: cat
age: 3

2. python script reading multiple documents in a yaml file

When python obtains yaml data, it needs to use the load ﹣ all function to parse all documents, and then read the data in the object

# When a yaml file contains multiple documents, the data in the documents are obtained separately
def get_yaml_load_all(yaml_file):
    # Open yaml file
    file = open(yaml_file, 'r', encoding="utf-8")
    file_data = file.read()
    file.close()
    all_data = yaml.full_load_all(file_data)
    for data in all_data:
        print(data)
current_path = os.path.abspath(".")
yaml_path = os.path.join(current_path, "config.yaml")
get_yaml_load_all(yaml_path)
"""Result
{'animal1': 'dog', 'age': 2}
{'animal2': 'cat', 'age': 3}
"""

IV. generating yaml documents from python objects

Convert list or dictionary data to yaml standard schema through yaml.dump() method

# Generating yaml documents from python objects
import yaml
def generate_yaml_doc(yaml_file):
    py_object = {'school': 'zhang',
                 'students': ['a', 'b']}
    file = open(yaml_file, 'w', encoding='utf-8')
    yaml.dump(py_object, file)
    file.close()
current_path = os.path.abspath(".")
yaml_path = os.path.join(current_path, "generate.yaml")
generate_yaml_doc(yaml_path)
"""Result
school: zhang
students:
-a
-b
"""

PS: in many online tutorials, it is said that the result of pyyaml library writing yaml file is not in standard yaml format, but after my personal test, I found that there is no such problem, so the ruamel module will not be introduced. My test environment is python 3.7, PyYAML 5.1.2.

Posted by slevytam on Thu, 21 Nov 2019 05:51:53 -0800