zoukankan      html  css  js  c++  java
  • yaml文件解析详解

    前言

    转载自:博客园Linux超的技术博客--https://www.cnblogs.com/linuxchao/

    yaml文件是什么?yaml文件其实也是一种配置文件类型,相比较ini,conf配置文件来说,更加的简洁,操作也更加简单,同时可以存放不同类型的数据,不会改变原有数据类型,所有的数据类型在读取时都会原样输出,yaml文件依赖python的第三方库PyYaml模块

    PyYaml安装

    yaml文件处理需要借助python的第三方库,因此我们第一步需要安装

    打开CMD执行命令: pip install PyYaml  注意:不要把Yaml写成Ymal

    读yaml文件

    yaml存字典并读取

    config.yaml

    复制代码
    cnblog: linux超
    address: BeiJing
    Company: petrochina
    age: 18
    now: 8.14
    empty1: null
    empty2: ~
    复制代码

    parseyaml.py

    复制代码
    """
    ------------------------------------
    @Time : 2019/8/14 20:37
    @Auth : linux超
    @File : parseYaml.py
    @IDE  : PyCharm
    @Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error!
    @QQ   : 28174043@qq.com
    @GROUP: 878565760
    ------------------------------------
    """
    import yaml
    
    
    with open("config.yml", "r", encoding="utf8") as f:
        context = yaml.load(f, Loader=yaml.FullLoader)
    print("读取内容", context, type(context))
    print(context["cnblog"], type(context["cnblog"]))
    print(context["age"], type(context["age"]))
    print(context["now"], type(context["now"]))
    print(context["empty1"], type(context["empty1"]))
    复制代码

    输出

    复制代码
    读取内容 {'cnblog': 'linux超', 'address': 'BeiJing', 'Company': 'petrochina', 'age': 18, 'now': 8.14, 'empty1': None, 'empty2': None} <class 'dict'>
    linux超 <class 'str'>
    18 <class 'int'>
    8.14 <class 'float'>
    None <class 'NoneType'>
    
    Process finished with exit code 0
    复制代码

    从输出结果及yaml文件内容你可以看到,当前输出的内容是一个字典类型,yaml文件中存储的字符串输出仍是字符串类型,int型仍是int型等,存储None类型可以使用null,~符号以及None,这也是区别ini配置文件的地方,且文件内容使用[key:value]的形式定义,当然key和value也可以使用双引号修饰;上面的yaml文件只存储了一组数据,你也可以存放多组数据,看下面的实例

    yaml存多组数据并读取

    config.yaml

    复制代码
    cnblog: linux超
    address: BeiJing
    Company: petrochina
    age: 18
    now: 8.14
    ---
    name: linux超
    gender: 男
    复制代码

    parseyaml.py

    复制代码
    """
    ------------------------------------
    @Time : 2019/8/14 20:37
    @Auth : linux超
    @File : parseYaml.py
    @IDE  : PyCharm
    @Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error!
    @QQ   : 28174043@qq.com
    @GROUP: 878565760
    ------------------------------------
    """
    import yaml
    
    
    with open("config.yml", "r", encoding="utf8") as f:
        context = yaml.load_all(f, Loader=yaml.FullLoader)
        print(context)
        for i in context:
            print(i)
    复制代码

    输出

    我是一个生成器 <generator object load_all at 0x01DDDAB0>
    {'cnblog': 'linux超', 'address': 'BeiJing', 'Company': 'petrochina', 'age': 18, 'now': 8.14}
    {'name': 'linux超', 'gender': ''}
    
    Process finished with exit code 0

    通过输出结果及yaml存储内容可以看出,当yaml文件存储多组数据在一个yaml文件中时,需要使用3个横杆分割,读取数据时需要使用load_all方法,而且此方法返回一个生成器,需要使用for循环迭代读取每一组数据下面再看一下yaml如何存储列表类型数据

    yaml存储列表并读取

    config.yaml

    - linux超
    - BeiJing
    - petrochina
    - 18
    - 8.14

    parseyaml.py

    复制代码
    """
    ------------------------------------
    @Time : 2019/8/14 20:37
    @Auth : linux超
    @File : parseYaml.py
    @IDE  : PyCharm
    @Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error!
    @QQ   : 28174043@qq.com
    @GROUP: 878565760
    ------------------------------------
    """
    import yaml
    
    
    with open("config.yml", "r", encoding="utf8") as f:
        context = yaml.load(f, Loader=yaml.FullLoader)
    print("读取内容", context, type(context))
    复制代码

    输出

    读取内容 ['linux超', 'BeiJing', 'petrochina', 18, 8.14] <class 'list'>
    
    Process finished with exit code 0

    当yaml文件存储列表数据时,需要使用一个横杠[- 元素]表示为列表的一个元素,除了列表以外还可以存储元组,或者说支持强制类型转换

    yaml存储元组并读取

    config.yml

    复制代码
    --- !!python/tuple # 列表转成元组
    - 1
    - 2
    - 3
    ---
    age: !!str 18 # int 类型转换为str
    复制代码

     parseyaml.py

    复制代码
    """
    ------------------------------------
    @Time : 2019/8/14 19:46
    @Auth : linux超
    @File : parseYaml.py
    @IDE  : PyCharm
    @Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error!
    @QQ   : 28174043@qq.com
    @GROUP: 878565760
    ------------------------------------
    """
    import yaml
    
    with open("./config.yml", "r", encoding="utf-8") as f:
        context = yaml.load_all(f, Loader=yaml.FullLoader)
        for i in context:
            print(i)
    复制代码

    输出

    (1, 2, 3)
    {'age': '18'}
    
    Process finished with exit code 0

    yaml文件使用两个!!号可以对数据进行类型转换,但是在我看来感觉没有用,当然可能我没遇见过需要做类型转化的情况;你还可以像下面这样存放更加复杂的数据,比如字典嵌套字典及列表

    config.yaml

    复制代码
    info:
      - user:
          username: linux超
          password: linuxxiaochao
    company:
      first: petrochina
      second: lemon teacher
    复制代码

    parseyaml.py

    复制代码
    """
    ------------------------------------
    @Time : 2019/8/14 20:37
    @Auth : linux超
    @File : parseYaml.py
    @IDE  : PyCharm
    @Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error!
    @QQ   : 28174043@qq.com
    @GROUP: 878565760
    ------------------------------------
    """
    import yaml
    
    
    with open("config.yml", "r", encoding="utf8") as f:
        context = yaml.load(f, Loader=yaml.FullLoader)
    print("读取内容
    ", context, type(context))
    复制代码

    输出

    读取内容
     {'info': [{'user': {'username': 'linux超', 'password': 'linuxxiaochao'}}], 'company': {'first': 'petrochina', 'second': 'lemon teacher'}} <class 'dict'>
    
    Process finished with exit code 0

    小结

    实际工作中大概就是存储字典,列表,或者相互嵌套的数据较常见,那么在存储和读取时需要掌握以下几点

    1.存储字典时,以[key:value]的形式定义

    2.存储列表时,需要使用[- 元素]表示列表

    3.存储多组数据时,需要每组数据之间使用3个横杠-分割分割

    4.数据嵌套时,需要注意缩进,和编写python代码的缩进规则相同,唯一不同是,yaml中的缩进只要统一即可不需要指定缩进多少

    5.读取一组数据时,直接使用load(stream, loader)方法, 读取多组数据时需要使用load_all(stream, loader)方法,此方法返回的是一个生成器,需要使用for循环读取每一组数据,还需要注意两个方法中的最好像我代码中一样传递loader参数为FullLoader,否则会报Warnning

    写yaml文件

    向yaml文件中写数据就比较简单了,直接使用dump方法和dump_all方法即可,无论多复杂的数据都可以直接写入,看实例

    dump写入一组数据

    复制代码
    """
    ------------------------------------
    @Time : 2019/8/14 19:46
    @Auth : linux超
    @File : parseYaml.py
    @IDE  : PyCharm
    @Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error!
    @QQ   : 28174043@qq.com
    @GROUP: 878565760
    ------------------------------------
    """
    import yaml
    
    response = {
        "status": 1,
        "code": "1001",
        "data": [
            {
                "id": 80,
                "regname": "toml",
                "pwd": "QW&@JBK!#&#($*@HLNN",
                "mobilephone": "13691579846",
                "leavemount": "0.00",
                "type": "1",
                "regtime": "2019-08-14 20:24:45.0"
            },
            {
                "id": 81,
                "regname": "toml",
                "pwd": "QW&@JBK!#&#($*@HLNN",
                "mobilephone": "13691579846",
                "leavemount": "0.00",
                "type": "1",
                "regtime": "2019-08-14 20:24:45.0"
            }
        ],
        "msg": "获取用户列表成功"
    }
    
    try:
        with open("./config.yml", "w", encoding="utf-8") as f:
            yaml.dump(data=response, stream=f, allow_unicode=True)
    except Exception as e:
        print("写入yaml文件内容失败")
        raise e
    else:
        print("写入yaml文件内容成功")
    复制代码

    生成的yaml文件内容

    复制代码
    code: '1001'
    data:
    - id: 80
      leavemount: '0.00'
      mobilephone: '13691579846'
      pwd: QW&@JBK!#&#($*@HLNN
      regname: toml
      regtime: '2019-08-14 20:24:45.0'
      type: '1'
    - id: 81
      leavemount: '0.00'
      mobilephone: '13691579846'
      pwd: QW&@JBK!#&#($*@HLNN
      regname: toml
      regtime: '2019-08-14 20:24:45.0'
      type: '1'
    msg: 获取用户列表成功
    status: 1
    复制代码

    dump_all写入多组数据

    复制代码
    """
    ------------------------------------
    @Time : 2019/8/14 19:46
    @Auth : linux超
    @File : parseYaml.py
    @IDE  : PyCharm
    @Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error!
    @QQ   : 28174043@qq.com
    @GROUP: 878565760
    ------------------------------------
    """
    import yaml
    
    response = {
        "status": 1,
        "code": "1001",
        "data": [
            {
                "id": 80,
                "regname": "toml",
                "pwd": "QW&@JBK!#&#($*@HLNN",
                "mobilephone": "13691579846",
                "leavemount": "0.00",
                "type": "1",
                "regtime": "2019-08-14 20:24:45.0"
            },
            {
                "id": 81,
                "regname": "toml",
                "pwd": "QW&@JBK!#&#($*@HLNN",
                "mobilephone": "13691579846",
                "leavemount": "0.00",
                "type": "1",
                "regtime": "2019-08-14 20:24:45.0"
            }
        ],
        "msg": "获取用户列表成功"
    }
    
    info = {
        "name": "linux超",
        "age": 18
    }
    
    try:
        with open("./config.yml", "w", encoding="utf-8") as f:
            yaml.dump_all(documents=[response, info], stream=f, allow_unicode=True)
    except Exception as e:
        print("写入yaml文件内容失败")
        raise e
    else:
        print("写入yaml文件内容成功")
    复制代码

    生成的yaml文件内容

    复制代码
    code: '1001'
    data:
    - id: 80
      leavemount: '0.00'
      mobilephone: '13691579846'
      pwd: QW&@JBK!#&#($*@HLNN
      regname: toml
      regtime: '2019-08-14 20:24:45.0'
      type: '1'
    - id: 81
      leavemount: '0.00'
      mobilephone: '13691579846'
      pwd: QW&@JBK!#&#($*@HLNN
      regname: toml
      regtime: '2019-08-14 20:24:45.0'
      type: '1'
    msg: 获取用户列表成功
    status: 1
    ---
    age: 18
    name: linux超
    复制代码

    小结

    1.写入一组数据直接使用dump方法或者dump_all方法也可

    2.写入多组数据只能使用dump_all方法

    3.写入数据时最重要的一点需要注意:如果你的数据包含中文,dump和dump_all 方法需要添加allow_unicode=True参数,否则中文写入后不会正常显示

    总结

    1.yaml存储数据规则-多组数据使用---分割,数据嵌套时注意缩进,存储字典使用[key: value]的形式,存储列表使用[- 元素]的形式,使用load读一组数据,使用load_all 可以读多组数据

    2.yaml文件写入一组数据直接使用dump方法,写入多组数据使用dump_all方法,注意写入数据带中文,需要指定参数allow_unicode=True

    感谢您的阅读,如有疑问欢迎在评论区进行讨论。 请大家支持原创,尊重原创,如要转载,请注明出处:“转载自:https://www.cnblogs.com/wolf-eye/”,谢谢!
  • 相关阅读:
    Struts2中的类型转换失败
    使用 paramsPrepareParamsStack 拦截器栈后的运行流程
    Action请求流程分析
    Struts2的默认拦截器执行顺序
    网络通信的整个流程
    路由和交换机工作原理
    网络编程之socket
    关于socket的setsockopt的使用
    socket工作原理深入分析
    网络通信协议(互联网协议)
  • 原文地址:https://www.cnblogs.com/wolf-eye/p/12181658.html
Copyright © 2011-2022 走看看