欢迎关注个人公众号 DailyOps
源站地址 配置文件Yaml之python版
什么是 yaml
yaml 可以做配置文件 ,但是yaml不仅仅是配置文件,其本身就是一种语言 ,有自己的语法和使用规范。
yaml文件后缀是有要求的,必须为yml 注意和ini文件做对比
yaml 文件介绍
1、基础规范
- 大小写敏感
- 使用缩进表示层级关系
- 缩进不允许使用tab,只允许空格
- 缩进的空格数不重要,只要相同层级的元素左对齐即可
- '#'表示注释
2、支持的类型
- 对象 这里的对象是指 键值对的集合,类似python字典
- 数组
- 纯量 类似我们说的常量,不可在分在变的。比如 字符串、布尔值、整数、浮点数、null、时间、日期等
3、yaml对象
格式 key: value 冒号分隔,且冒号后面得有个空格
比如
site_name: Colinspace website
site_url: http://blog.colinspace.com
mysql_db: {host: 192.168.1.10, user: demouser}
mysql_db:
host: 192.168.1.10
user: demouser
4、yaml数组
数组是以中横线 - 开头的一组配置,且支持多维数组。比如
fruits:
- apple
- banana
- orange
fruits: ['apple', 'banana', 'orange']
数组是有个数组名的,也就是配置的key,value是- 开头的一组数据组成的数组,该组数据对其方式保持一致。
换句话说 中横线开头的,其对齐方式一样的元素组成一个数组 ,重点记住这句话,因为这个是理解多维数组 的关键所在
5、多维数组
我们先看几个配置
config_multi_array:
-
- apple
- banana
- orange
-
- potato
- tomato
- cucumber
config_like_multi_array:
- fruits:
- apple
- banana
- orange
- vegetables:
- potato
- tomato
- cucumber
config_like_multi_array_v2:
-
fruits:
- apple
- banana
- orange
-
vegetables:
- potato
- tomato
- cucumber
config_like_multi_array_v3:
- fruits
- apple
- banana
- orange
- vegetables
- potato
- tomato
- cucumber
config_like_multi_array_v4:
fruits:
- apple
- banana
- orange
vegetables:
- potato
- tomato
- cucumber
这里我们先给出5种key配置方式的最终的结果如下,发现只有config_multi_array 是真正的二维数组。
"config_multi_array": [
[
"apple",
"banana",
"orange"
],
[
"potato",
"tomato",
"cucumber"
]
],
"config_like_multi_array": [
{
"fruits": [
"apple",
"banana",
"orange"
]
},
{
"vegetables": [
"potato",
"tomato",
"cucumber"
]
}
],
"config_like_multi_array_v2": [
{
"fruits": [
"apple",
"banana",
"orange"
]
},
{
"vegetables": [
"potato",
"tomato",
"cucumber"
]
}
],
"config_like_multi_array_v3": [
"fruits - apple - banana - orange",
"vegetables - potato - tomato - cucumber"
],
"config_like_multi_array_v4": {
"fruits": [
"apple",
"banana",
"orange"
],
"vegetables": [
"potato",
"tomato",
"cucumber"
]
},
从结果也证明 config_multi_array 是真正的二维数组,所以我们得知,数组一定是- 开头,
-
如果要表示多维数组,那么第一维的- 后面不能接任何东西,比如 config_multi_array -
如果后面接了 key 但是 key 紧接着有冒号: 的话那么就是对象,该 key 就是对象的名称;例如这里的 config_like_multi_array 和 config_like_multi_array_v2 ,这两个的效果是等价的; 这种做法其实在 "数组" 中嵌套 "键值对" 为什么? 记得上面说的 中横线开头的,其对齐方式一样的元素组成一个数组 ,所以这两个肯定是数组,而且有两个元素。 带冒号: 又符合 key:value 对象的组成,所以每个元素都是对象,对象名名是key,值是个数组 -
如果后面接了 key 但是 key 紧接着没有冒号: 的话,他就会和后面的数组元素一起组成一个数组,比如这里的 config_like_multi_array_v3 ,其实这种配置方式是"错误"的 -
另外比如第五种配置config_like_multi_array_v4 方式,没有- 开头,所以就是个对象,每个对象的值是个数组,这种方式其实是种复合结构,或者叫 在 "键值对" 中嵌套 "数组"
6、复合结构
符合结构其实就是 对象和数组的结合使用了,比如
composite_structure:
name: compound_demo
classes:
-
class_one: 1
name: 三年一班
students: 32
-
class_two: 2
name: 三年二班
students: 35
这里 composite_structure 对象 中有对象结构name 和 classes ,而对象classes 的值是个数组,有两个元素,每个元素是个对象,又由三个对象构成
python操作yaml文件
一个yaml文件中可以存在多个部分,每个部分开头 ---
-
python读取解析yaml文件 yaml.load(f_handler, Loader=yaml.Loader) 解析单部分文件 yaml.load_all(f_handler, Loader=yaml.FullLoader) 解析多部份文件 -
python 写入配置到 yaml 文件 yaml.dump(python_dict_obj, f_handler) -
其他方法 loader.items() 列出所有配置项(key和value) loader.keys() 列出所有配置项的key loader.values() 列出所有配置项的value loader.get(key) 获取某个配置项key对应的值
python 操作 yaml 脚本#!/usr/bin/env python
encoding: utf-8
Author: colinspace.com
Desc: python yaml demo
import sys import yaml import json
yml_file = “demo.yml” yml_file_multi = “multi.yml”
print("\n==> 转化yaml内容为字典或者列表 - 单部分") with open(yml_file, ‘r’, encoding=‘utf-8’) as f: try: loader = yaml.load(f, Loader=yaml.Loader) # type is dict with single quotes; can’t use python -m json.tool to format result # print(type(loader)) # print(loader)
# type is str with double quotes
# print(type(json.dumps(loader)))
print(json.dumps(loader))
except Exception as e: print(e)
print("\n==> 转化yaml内容为字典或者列表 - 多部分") with open(yml_file_multi, ‘r’, encoding=‘utf-8’) as f: try: # loader here is generator loader = yaml.load_all(f, Loader=yaml.FullLoader) for item in loader: print(json.dumps(item))
except Exception as e: print(e)
print("\n==> 尝试写入配置到yaml文件") py_dict = { “cache”: { “host”: “192.168.1.11”, “port”: 3306 }, “languages”: [“python”, “golang”, “Java”] }
with open(“demo_write.yml”, “w”, encoding=“utf-8”) as f: yaml.dump(py_dict, f)
print("==> 写入之后的结果") with open(“demo_write.yml”, “w”, encoding=“utf-8”) as f: print(f.read())
import sys
import yaml
import json
yml_file = "demo.yml"
yml_file_multi = "multi.yml"
print("\n==> 转化yaml内容为字典或者列表 - 单部分")
with open(yml_file, 'r', encoding='utf-8') as f:
try:
loader = yaml.load(f, Loader=yaml.Loader)
print(json.dumps(loader))
except Exception as e:
print(e)
print("\n==> 转化yaml内容为字典或者列表 - 多部分")
with open(yml_file_multi, 'r', encoding='utf-8') as f:
try:
loader = yaml.load_all(f, Loader=yaml.FullLoader)
for item in loader:
print(json.dumps(item))
except Exception as e:
print(e)
print("\n==> 尝试写入配置到yaml文件")
py_dict = {
"cache": {
"host": "192.168.1.11",
"port": 3306
},
"languages": ["python", "golang", "Java"]
}
with open("demo_write.yml", "w", encoding="utf-8") as f:
yaml.dump(py_dict, f)
print("==> 写入之后的结果")
with open("demo_write.yml", "w", encoding="utf-8") as f:
print(f.read())
结果如下
扩展
1、windows下no module named pip 报错
在windows的 cmd 命令行中输入如下命令进行修正
python -m ensurepip
如果想要升级 pip 需要执行如下命令
python -m pip install -U pip
2、python json.tool 中文乱码
显示乱码的原因是,json为了安全会把内容都转义为ascii编码 ,我们可以通过参数ensure_ascii 不让json强行将内容都转义为ascii编码,中文原样输出即可。
python2 和 python3 的方式有所不同
python2 需要修改源码的配置,在系统安装路径下找到 json/tools.py 文件,添加参数配置ensure_ascii=False ,比如
json.dump(obj, outfile, sort_keys=True, indent=4, separators=(',', ': '))
修改为
json.dump(obj, outfile, sort_keys=True, indent=4, separators=(',', ': '), ensure_ascii=False)
python3 添加参数 --no-ensure-ascii 即可 ,我们从其输出用法可以得到
usage: python -m json.tool [-h] [--sort-keys] [--no-ensure-ascii] [--json-lines]
[--indent INDENT | --tab | --no-indent | --compact]
[infile] [outfile]
所以使用如下命令
python demo_yaml.py | python -m json.tool --no-ensure-ascii
|