數據及配置文件之爭
數據及文件通常有三種類型:
- 配置文件型:如ini,conf,properties文件,適合存儲簡單變量和配置項,最多支持兩層,不適合存儲多層嵌套數據
- 表格矩陣型:如csv,excel等,適合於存儲大量同類數據,不適合存儲層級結構的數據
- 多層嵌套型:如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"
- 數字:
123
或123.45
- true/false:
true
/false
,TRUE
/FALSE
,True
/False
或on
/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