Ansible系列-基础篇-配置文件Yaml之python版

18 篇文章 0 订阅
10 篇文章 1 订阅

欢迎关注个人公众号 DailyJobOps

源站地址 配置文件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}
# 嵌套配置也可以按照层级缩进配置,注意是空格缩进,而不是tab
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

# it's array, but not tow-dimension array
# one-dimension array with two elements
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_arrayconfig_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 对象 中有对象结构nameclasses,而对象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())

#!/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())

结果如下




扩展

1、windows下no module named pip 报错

在windows的 cmd 命令行中输入如下命令进行修正

python -m ensurepip

如果想要升级 pip 需要执行如下命令

# 不能直接使用 pip install -U pip 
# -U 等效于 --upgrade 
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
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值