Python3操作YAML文件


數據及配置文件之爭

數據及文件通常有三種類型:

  1. 配置文件型:如ini,conf,properties文件,適合存儲簡單變量和配置項,最多支持兩層,不適合存儲多層嵌套數據
  2. 表格矩陣型:如csv,excel等,適合於存儲大量同類數據,不適合存儲層級結構的數據
  3. 多層嵌套型:如XML,HTMl,JSON、YAML,TOML等,適合存儲單條或少數多層嵌套數據,不適合存儲大量數據

YAML兼容JSON格式,簡潔,強大,靈活,可以很方便的構造層級數據並快速轉為Python中的字典。

YAML簡介

YAML(YAML Ain't Markup Language)即一種反標記(XML)語言。強調數據為中心,而非標記。YAML大小寫敏感,使用縮進代表層級關系。
YAML中支持對象Object(對應Python中的字典), 數組Array(對應Python中的列表)以及常量(字符串、數字(int/float),true/false/null)。
相比於JSON格式,YAML免除了雙引號,逗號,大括號,中括號等,(當然也支持原始的JSON格式),並且支持注釋,類型轉換,跨行,錨點,引用及插入等等。

基本格式

  • 對象:使用key: value表示,冒號后面有一個空格,也可以是使用{key: value} (flow流格式)或{"key": "value"}表示
  • 數組:使用- value表示,-后面有一個空格,每項一行,也可以使用[value1,value2,value3,...] (flow流格式)或["value1", "value2", "value3", ...]
  • 字符串:abc"abc"
  • 數字:123123.45
  • true/false:true/false,TRUE/FALSE,True/Falseon/off, ON/OFF, On/Off
  • null: null,NULL, Null~

示例文件demo.yaml:

# 注釋:示例yaml文件
name: Cactus
age: 18
skills: 
  -
    - Python
    - 3
  -
    - Java
    - 5
has_blog: true
gf: ~

相當於以下JSON格式

{
  "name": "Cactus",
  "age": 18,
  "skills": [
    [
      "Python",
      3
    ],
    [
      "Java",
      5
    ]
  ],
  "has_blog": true,
  "gf": null
}

類型轉換

使用!!str, !!float等可以將默認類型轉為指定類型,如

- !!float 3
- !!str 4
- !!str true

對應JSON格式

[
  3.0,
  "4",
  "true"
]

多行文本及拼接

  • | 保留多行文本(保留換行符)
  • > 將多行拼接為一行

示例:

a: |
  我
  喜歡你

b: >
  我
  不喜歡你
  才怪

對應JSON格式

{
  "a": "我\n喜歡你\n",
  "b": "我 不喜歡你 才怪"
}

錨點,引用及插入

-:后 加上&錨點名為當前字段建立錨點,下面可使用*錨點名引用錨點,或使用<<: *錨點名直接將錨點數據插入到當前的數據中,示例如下:

users:
  - &zs
    name: 張三
    password: !!str 123456
  - &ls
    name: 李四
    password: abcdefg

case1:
  login: *zs

case2:
  user:
    <<: *ls
    age: 20

對應JSON格式:

{
  "users": [
    {
      "name": "張三",
      "password": "123456"
    },
    {
      "name": "李四",
      "password": "abcdefg"
    }
  ],
  "case1": {
    "login": {
      "name": "張三",
      "password": "123456"
    }
  },
  "case2": {
    "user": {
      "name": "李四",
      "password": "abcdefg",
      "age": 20
    }
  }
}

Python操作YAML文件及字符串

需要安裝pyyaml, pip install pyyaml

和JSON文件類似,yaml也提供load和dump兩種方法。

  • yaml.load()yaml.safe_load(YAML字符串或文件句柄):yaml -> 字典,如yaml中有中文,需要使用 字符串.encode('utf-8')或打開文件時指定encoding='utf-8'
  • yaml.dump(字典):默認為flow流格式,即字典{b': {'c': 3, 'd': 4}},會被轉為b: {c: 3, d: 4}形式,可以使用default_flow_style=False關閉流模式

由於yaml.load()支持原生Python對象,不安全,建議使用yaml.safe_load()

示例1:yaml字符串 -> 字典

import yaml
yaml_str = '''
name: Cactus
age: 18
skills: 
  -
    - Python
    - 3
  -
    - Java
    - 5
has_blog: true
gf: ~
'''
print(yaml.safe_load(yaml_str)) 

打印結果:

{'name': 'Cactus', 'age': 18, 'skills': [['Python', 3], ['Java', 5]], 'has_blog': True, 'gf': None}

如果有中文,可以使用yaml.load(yaml_str.encoding('utf-8))

示例2:yaml文件 -> 字典

import yaml
with open('demo.yaml', encoding='utf-8') as f:   # demo.yaml內容同上例yaml字符串 
    print(yaml.safe_load(f))

打印結果同上例。

字典 -> yaml字符串或文件

import yaml
dict_var = {'name': 'Cactus', 'age': 18, 'skills': [['Python', 3], ['Java', 5]], 'has_blog': True, 'gf': None}
print(yaml.dump(dict_var,))  # 轉為字符串,使用默認flow流格式
with open('demo5.yaml', 'w', encoding='utf-8') as f:
    yaml.dump(dict_var, f, default_flow_style=False)  # 寫入文件,不是用flow流格式

打印內容:

age: 18
gf: null
has_blog: true
name: Cactus
skills:
- [Python, 3]
- [Java, 5]

1demo5.yaml1文件內容:

age: 18
gf: null
has_blog: true
name: Cactus
skills:
- - Python
  - 3
- - Java
  - 5

更多操作可參考pyyaml官方文檔:https://pyyaml.org/wiki/PyYAMLDocumentation


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM