天天看点

YAML简介和PyYAML安全操作YAML支持的类型YAML的优点:yaml的基本语法python操作

YAML 是 “YAML Ain’t a Markup Language”(YAML 不是一种标记语言)的递归缩写,是一种人类易读的数据序列化语言。它通常运用在一些数据代码分离场合:用于配置文件,但也用于数据存储(例如调试输出)或传输(例如文档标题)。YAML 的配置文件后缀为 .yml,如:runoob.yml 。

YAML支持的类型

  • 对象

    键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)

  • 数组

    一组按次序排列的值,又称为序列(sequence) / 列表(list)

  • 纯量

    单个的、不可再分的值

YAML的优点:

可读性好;和脚本语言的交互性好;有一个一致的信息模型;易于实现;可以基于流来处理;表达能力强,扩展性好。

yaml的基本语法

1、大小写敏感;

2、使用缩进表示层级关系,缩进只可以使用空格,不允许使用tab,遵守左对齐即可;

3、列表中项通过“-”表示,字典中的通过“:”表示;

4、# 表示注释,和python表示注释一样。

  • 数值
number: 12.30
number2: 6.8523015e+5  #科学计数法表示
number3: 0b1010_0111_0100_1010_1110    #二进制表示
           
  • 布尔值用
  • null表示
  • 日期时间
  • 转换数据类型。
int_to_str: !!str 123
bool_to_str: !!str true
           

一个比较完整的例子:

# 这是注释
name: Joe
age: 18
languages:
  - Python 
websites:
  YAML: yaml.org 
  Python: python.org 
           

python操作

安装

pip install pyyaml
           

加载

PyYAML加载YAMl文件有8种方法:

load()

load_all()

safe_load()

safe_load_all()

unsafe_load()

unsafe_load_all()

full_load()

full_load_all()

。建议使用安全的safe_load()函数加载YAML文件。

# coding:utf-8
import yaml


with open('test.yaml','r',encoding='utf-8') as f:
    y = yaml.safe_load(f.read())
    print(y)
           

结果

>>>{'name': 'J', 'age': 18, 'text': {'name': '软件'}, 'skill': [{'name1': '测试'}, {'name2': '功能'}]}
           

关于PyYAML的load()方法的安全问题

PyYAML开发者明确知悉load()存在安全问题,但因为向前兼容的问题没有将load()改为默认以安全方式加载。建议在调用load()时必须以

Loader=

指定加载方式来缓解,因此没有该参数情况下调用load()会产生警告。

在PyYAML 5.1+之前,load()可以轻松利用该函数来调用任何Python函数。这意味着它可以使用调用任何系统命令

os.system()

。这是一个简单的示例:

pyyaml-5.3.1以后,仍然存在一些琐碎的漏洞利用,不要在不受信任的数据上使用load,特别是FullLoader加载。

同时,PyYAML作者有意和Pickle序列化兼容,会导致不可信数据被不安全地加载。

  • 除去警告

load时按需指定参数Loader即可:

加载器 描述
BaseLoader 仅加载最基本的YAML。所有标量都作为字符串加载。
SafeLoader 安全地加载YAML语言的子集。建议用于加载不可信的输入。
FullLoader 加载完整的YAML语言。避免了一些执行代码。
UnsafeLoader 不受信任的输入可能执行其他代码。

后续FullLoader可能会弃用。

  • 强制禁止警告

写出

PyYAML写出有四个函数:

dump()

dump_all()

safe_dump()

safe_dump_all()

,下面以safe_dump()为例:

import yaml

config = {'a': ['1', 'b']}
    with open('test.yaml', 'w', encoding='utf8') as f:
        yaml.safe_dump(config, f)