Python使用PyYAML庫讀寫yaml配置文件

一. yaml文件介紹

yaml是一個專門用來寫配置文件的語言。python

1. yaml文件規則

  • 區分大小寫;
  • 使用縮進表示層級關係;
  • 使用空格鍵縮進,而非Tab鍵縮進
  • 縮進的空格數目不固定,只須要相同層級的元素左側對齊;
  • 文件中的字符串不須要使用引號標註,但若字符串包含有特殊字符則需用引號標註;
  • 註釋標識爲#

2. yaml文件數據結構

  • 對象:鍵值對的集合(簡稱 "映射或字典")
  • 鍵值對用冒號 「:」 結構表示,冒號與值之間需用空格分隔
  • 數組:一組按序排列的值(簡稱 "序列或列表")
  • 數組前加有 「-」 符號,符號與值之間需用空格分隔
  • 純量(scalars):單個的、不可再分的值(如:字符串、bool值、整數、浮點數、時間、日期、null等)
  • None值可用null可 ~ 表示

2、python中讀取yaml配置文件

1. 前提條件

python中讀取yaml文件前須要安裝pyyaml和導入yaml模塊:數組

  • 使用yaml須要安裝的模塊爲pyyaml(pip3 install pyyaml);
  • 導入的模塊爲yaml(import yaml)

2. 讀取yaml文件數據

python經過open方式讀取文件數據,再經過load函數將數據轉化爲列表或字典;數據結構

import yaml
import os

def get_yaml_data(yaml_file):
    # 打開yaml文件
    print("***獲取yaml文件數據***")
    file = open(yaml_file, 'r', encoding="utf-8")
    file_data = file.read()
    file.close()
    
    print(file_data)
    print("類型:", type(file_data))

    # 將字符串轉化爲字典或列表
    print("***轉化yaml數據爲字典或列表***")
    data = yaml.full_load(file_data)
    print(data)
    print("類型:", type(data))
    return data
current_path = os.path.abspath(".")
yaml_path = os.path.join(current_path, "config.yaml")
get_yaml_data(yaml_path)

"""
***獲取yaml文件數據***
# yaml鍵值對:即python中字典
usr: my
psw: 123455
類型:<class 'str'>
***轉化yaml數據爲字典或列表***
{'usr': 'my', 'psw': 123455}
類型:<class 'dict'>
"""

3. yaml文件數據爲鍵值對

(1)yaml文件中內容爲鍵值對:函數

# yaml鍵值對:即python中字典
usr: my
psw: 123455
s: " abc\n"

python解析yaml文件後獲取的數據:測試

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

(2)yaml文件中內容爲「鍵值對'嵌套"鍵值對"spa

# yaml鍵值對嵌套:即python中字典嵌套字典
usr1:
  name: a
  psw: 123
usr2:
  name: b
  psw: 456

python解析yaml文件後獲取的數據:scala

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

(3)yaml文件中「鍵值對」中嵌套「數組」code

# yaml鍵值對中嵌套數組
usr3:
  - a
  - b
  - c
usr4:
  - b

python解析yaml文件後獲取的數據:對象

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

4. yaml文件數據爲數組

(1)yaml文件中內容爲數組教程

# yaml數組
- a
- b
- 5

python解析yaml文件後獲取的數據:

['a', 'b', 5]

(2)yaml文件「數組」中嵌套「鍵值對」

# yaml"數組"中嵌套"鍵值對"
- usr1: aaa
- psw1: 111
  usr2: bbb
  psw2: 222

python解析yaml文件後獲取的數據:

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

5. yaml文件中基本數據類型:

# 純量
s_val: name              # 字符串:{'s_val': 'name'}
spec_s_val: "name\n"    # 特殊字符串:{'spec_s_val': 'name\n'
num_val: 31.14          # 數字:{'num_val': 31.14}
bol_val: true           # 布爾值:{'bol_val': True}
nul_val: null           # null值:{'nul_val': None}
nul_val1: ~             # null值:{'nul_val1': None}
time_val: 2018-03-01t11:33:22.55-06:00     # 時間值(iso8601格式):{'time_val': datetime.datetime(2018, 3, 1, 17, 33, 22, 550000)}
date_val: 2019-01-10    # 日期值:{'date_val': datetime.date(2019, 1, 10)}

6. yaml文件中引用

yaml文件中內容

animal3: &animal3 fish
test: *animal3

python讀取的數據

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

3、python中讀取多個yaml文檔

1. 多個文檔在一個yaml文件,使用 --- 分隔方式來分段

如:yaml文件中數據

# 分段yaml文件中多個文檔
---
animal1: dog
age: 2
---
animal2: cat
age: 3

2. python腳本讀取一個yaml文件中多個文檔方法

python獲取yaml數據時需使用load_all函數來解析所有的文檔,再從中讀取對象中的數據

# yaml文件中含有多個文檔時,分別獲取文檔中數據
def get_yaml_load_all(yaml_file):
    # 打開yaml文件
    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)
"""結果
{'animal1': 'dog', 'age': 2}
{'animal2': 'cat', 'age': 3}
"""

4、python對象生成yaml文檔

經過yaml.dump()方法將列表或字典數據進行轉化yaml標準模式

# 將python對象生成yaml文檔
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)
"""結果
school: zhang
students:
-a
-b
"""

PS: 在網上看到不少教程中都說pyyaml庫寫yaml文件結果不是標準的yaml格式,可是通過我我的測試後發現並無這方面的問題,所以, ruamel模塊就再也不介紹了。本人測試的環境是python 3.7,PyYAML 5.1.2。

相關文章
相關標籤/搜索