YAML教程

版权声明:本文为博主原创文章,如果转载请标明出处,谢谢- -!...如有错误,请大家帮忙指正...联系邮箱401865981@qq.com https://blog.csdn.net/lis_12/article/details/80352084

YAML

  • 设计目标:方便读写
  • 用处:专门用来写配置文件的语言,一种通用的数据串行化格式

基本语法

  • 大小写敏感
  • 使用缩进表示层级关系
  • 缩进时不允许使用Tab键,只允许使用空格。
  • 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
  • “#” 表示注释,从这个字符一直到行尾,都会被解析器忽略

支持的数据结构:

  • 字典:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 对象
  • 数组:一组按次序排列的值,又称为序列(sequence) / 列表(list)
  • 纯量(scalars):单个的、不可再分的值,即基本数据类型

注意点

  • 重复定义时,后定义的会覆盖前面定义的值
  • 如果值为 int, float, bool等类型,解析后会转换为对应的类型

字典

键值对,使用冒号结构表示。

# {k1: v1}
hash:
  k1: v1
  k2: true
  k3: 1
  k4: 1.0001

# or
# { k1:v1, k2:v2 }, k: v 间的空格不能省略
hash: { k1: v1, k2: true, k3: 1, k4: 1.0001 } 

数组

一组连词线开头的行,构成一个数组。

# ['Cat', 'Dog', 'Goldfish']
listname
  - Cat
  - Dog
  - Goldfish

如果数据结构的子成员是一个数组,则可以在该项下面缩进一个空格。

# [# ['Cat', 'Dog', 'Goldfish'], ]
listname
  -
    - Cat
    - Dog
    - Goldfish

行内表示法

# { animal: [ 'Cat', 'Dog' ] }
animal: [Cat, Dog]

纯量

纯量是最基本的、不可再分的值。

  • 字符串
  • 布尔值
  • 整数
  • 浮点数
  • Null
  • 时间
  • 日期

表现形式:

  • 数值类,直接以字面量的形式表示
# num: 12.30
num: 12.30
  • 布尔,true 和 false 表示
# {flag: true}
flag: true
  • null 用~表示
# {parent: null}
parent: ~
  • 时间,采用ISO8601格式
# { iso8601: new Date('2001-12-14t21:59:43.10-05:00') }
iso8601: 2001-12-14t21:59:43.10-05:00 
  • 日期
# { date: new Date('1976-07-31') }
date: 1976-07-31
  • 强制类型转换,双!
# { e: '123', f: 'true' }
e: !!str 123
f: !!str true
  • 字符串
# { str: '这是一行字符串' }
str: 这是一行字符串

# 字符串之中包含空格或特殊字符,需要放在引号之中
# { str: '内容: 字符串' }
str: '内容: 字符串'

# 单引号和双引号都可以使用,双引号不会对特殊字符转义
# { s1: '内容\\n字符串', s2: '内容\n字符串' }
s1: '内容\n字符串'
s2: "内容\n字符串"

# 单引号之中如果还有单引号,必须连续使用两个单引号转义
# { str: 'labor\'s day' }
str: 'labor''s day'

# 字符串可以写成多行,从第二行开始,必须有一个单空格缩进。换行符会被转为空格
# { str: '这是一段 多行 字符串' }
str: 这是一段
  多行
  字符串

# 多行字符串可以使用|保留换行符,也可以使用>折叠换行
# { this: 'Foo\nBar\n', that: 'Foo Bar\n' }
this: |
  Foo
  Bar
that: >
  Foo
  Bar

# +表示保留文字块末尾的换行,-表示删除字符串末尾的换行。
# { s1: 'Foo\n', s2: 'Foo\n\n\n', s3: 'Foo' }
s1: |
  Foo
s2: |+
  Foo
s3: |-
  Foo  

# 引用

锚点&和别名*,可以用来引用。

  • &用来建立锚点,类似于声明变量
  • *用来引用锚点,类似于引用变量
  • <<表示合并到当前数据(如果变量名重复也会覆盖)
# example, 文件名为test2.yml
var: &var 111

tag1: &tag1
  - *var
  - m2
# 等价于
#tag1: &tag1
#  - 111
#  - m2

tag2:
  - *tag1
  - *var
  - m3
  - m4
# 等价于  
#tag2:
#  - [111, m2]
#  - 111
#  - m3
#  - m4

redis: &redis
  r_host: redis_host
  r_port: redis_port

mysql: &mysql
  m_host: mysql_host
  m_port: mysql_port

dev1:
  <<: *redis
  <<: *mysql
# 等价于
#dev1:
#  r_host: redis_host
#  r_port: redis_port
#  m_host: mysql_host
#  m_port: mysql_port

dev2:
  redis: *redis
  mysql: *mysql
# 等价于
#dev2:
#  redis: { r_host: redis_host, r_port: redis_port }
#  mysql: { m_host: mysql_host, m_port: mysql_port } 

Python2.7 example

#!/usr/bin/python
# -*- coding: utf-8 -*-
import yaml

def print_dict(data, prefix=""):
    if isinstance(data, dict):
        l = data.keys()
        l.sort()
        for k in l:
            pre = k if not prefix else "%s_%s" % (prefix, k)
            print_dict(data[k], pre)
    else:
        print "%s ->%s" % (prefix, data)
        if isinstance(data, (list, tuple)):
            for i in data:
                print type(i), i
        else:
            print type(data), data
        print


def parse(filepath):
    with open(filepath) as f:
        config = yaml.load(f)
    print type(config)
    print_dict(config)


if __name__ == '__main__':
    # parse("test1.yml")
    parse("test2.yml")

test1.yml如下

# test1.yaml
a_map1:
  k1: v1
  k2: true
  k3: 1
  k4: 1.0001
  # 会覆盖前面定义的k4
  k4: 2.0002

# 与map1等价
a_map2: { k1: v1, k2: true, k3: 1, k4: 1.0001, k4: 2.0002 }

b_list:
  - 1
# 覆盖前面定义的list
b_list:
  - v1
  - true
  - 1
  - 1.0001
  -
    - 1
    - 2
    - 3

b_list1: [v1, true, 1, 1.0001, [1, 2, 3]]

c_int: 1
c_bool: true
c_str1: str
# int,bool强制->str
c_str2: !!str 123
c_str3: !!str true
c_str4: str
c_null: null

学习链接

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页