YAML基本语法

1. 简介

YAML 是一种较为人性化的数据序列化语言,可以配合目前大多数编程语言使用。

YAML 的语法比较简洁直观,特点是使用空格来表达层次结构,其最大优势在于数据结构方面的表达,所以 YAML 更多应用于编写配置文件,其文件一般以 .yaml 为后缀。

它的基本语法规则如下:

  • 大小写敏感
  • 使用缩进表示层级关系
  • 缩进时不允许使用Tab键,只允许使用空格
  • 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可

#表示注释,从这个字符一直到行尾,都会被解析器忽略。

YAML 支持的数据结构有三种。

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

在一个文件中可以使用---表示文件开头...表示文件结尾,这样一个文件里等于同时保存多个文件了。

2. 对象

  • 使用key: value形式表示

注意,冒号之后要加空格,否则无法解析

father: dad
Father: Dad
{ father: 'dad', Father: 'Dad' }

这里由于大小写敏感,是两个对象


  • 支持多层嵌套(用缩进表示层级关系
father:
  child1: Jack
  child2: Bob
{ father: { child1: 'Jack', child2: 'Bob' } }

  • 支持**流式风格( Flow style)**的语法(用花括号包裹,用逗号加空格分隔,类似 JSON)
father: {child1: Jack, child2: Bob}
{ father: { child1: 'Jack', child2: 'Bob' } }

3. 数组

  • 一组以区块格式(Block Format)(即“破折号+空格”)开头的数据组成一个数组
animals:
  - Cat
  - Dog
  - Goldfish
{ animals: [ 'Cat', 'Dog', 'Goldfish' ] }
  • 同时也支持内联格式(Inline Format)来表达(用方括号包裹,逗号加空格分隔,类似 JSON)
values: [value1, value2, value3]
{ values: [ 'value1', 'value2', 'value3' ] }
  • 支持多维数组(用缩进表示层级关系
values:
  -
    - value1
    - value2
  -
    - value3
    - value4
{ values: [ [ 'value1', 'value2' ], [ 'value3', 'value4' ] ] }

注意,第2行和第5行不能添加东西,否则解析出来就不是二维数组了,如下面反例

values:
  - sx1
    - value1
    - value2
  - sx2
    - value3
    - value4
{ values: [ 'sx1 - value1 - value2', 'sx2 - value3 - value4' ] }

4. 纯量

纯量是最基本的,不可再分的值,包括:

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

下面是纯量的使用示例

boolean: 
    - TRUE  #true,True都可以
    - FALSE  #false,False都可以
float:
    - 3.14
    - 6.8523015e+5  #可以使用科学计数法
int:
    - 123
    - 0b1010_0111_0100_1010_1110    #二进制表示
null:
    nodeName: 'node'
    parent: ~  #使用~表示null
string:
    - 哈哈
    - 'Hello world'  #可以使用双引号或者单引号包裹特殊字符
    - newline
      newline2       #字符串可以拆成多行,每一行会被转化成一个空格
date:
    - 2018-02-17     #日期必须使用ISO 8601格式,即yyyy-MM-dd
datetime: 
    -  2018-02-17T15:02:31+08:00    #时间使用ISO 8601格式,时间和日期之间使用T连接,最后使用+代表时区

JSON显示如下:

{ boolean: [ true, false ],
  float: [ 3.14, 685230.15 ],
  int: [ 123, 685230 ],
  null: { nodeName: 'node', parent: null },
  string: [ '哈哈', 'Hello world', 'newline newline2' ],
  date: [ Sat Feb 17 2018 08:00:00 GMT+0800 (中国标准时间) ],
  datetime: [ Sat Feb 17 2018 15:02:31 GMT+0800 (中国标准时间) ] }

4.1 字符串

字符串是最常见,也是最复杂的一种数据类型。

  • 字符串一般不需要用引号包裹,但是如果字符串中使用了反斜杠“\”开头的转义字符就必须使用引号包裹

    strings:
      - Hello without quote        # 不用引号包裹
      - Hello
        world                      # 拆成多行后会自动在中间添加空格
      - 'Hello with single quotes' # 单引号包裹
      - "Hello with double quotes" # 双引号包裹
      - "I am fine. \u263A"        # 使用双引号包裹时支持 Unicode 编码
      - "\x0d\x0a is \r\n"         # 使用双引号包裹时还支持 Hex 编码
      - 'He said: "Hello!"'        # 单双引号支持嵌套"
      - \n \r             
      - '\n \r'                    
      - "\n \r"                    
    

    其JSON如下:

    { strings: 
       [ 'Hello without quote',
         'Hello world',
         'Hello with single quotes',
         'Hello with double quotes',
         'I am fine. ☺',
         '\r\n is \r\n',
         'He said: "Hello!"',
         '\\n \\r',
         '\\n \\r',
         '\n \r' ] }
    

    自己注意一下不同引号对结果的影响

  • 对于多行的文字,YAML 提供了两种特殊的语法支持

    • 保留换行(Newlines preserved)

      使用**竖线符“ | ”**来表示该语法,每行的缩进和行尾空白都会被去掉,而额外的缩进会被保留

      lines: |
        我是第一行
        我是第二行
          我是吴彦祖
            我是第四行
        我是第五行
      

      JSON格式如下:

      { lines: '我是第一行\n我是第二行\n  我是吴彦祖\n    我是第四行\n我是第五行\n' }
      
    • 折叠换行(Newlines folded)

      使用**右尖括号“ > ”**来表示该语法,只有空白行才会被识别为换行,原来的换行符都会被转换成空格

      lines: >
        我是第一行
        我也是第一行
        我仍是第一行
        我依旧是第一行
      
        我是第二行
        这么巧我也是第二行
      

      其JSON格式如下:

      { lines: '我是第一行 我也是第一行 我仍是第一行 我依旧是第一行\n我是第二行 这么巧我也是第二行\n' }
      

      注意,此方法最后一行末尾换行符会被识别

    • 还可以用+-来选择是否保留蚊子块末尾的换行符

      s1: |
        Foo
      s2: |+
        Foo
      s3: |-
        Foo
      

      其JSON如下:

      { s1: 'Foo\n', s2: 'Foo\n', s3: 'Foo' }
      

4.2 布尔值

  • “true”、“True”、“TRUE”、“yes”、“Yes”和“YES”皆为
  • “false”、“False”、“FALSE”、“no”、“No”和“NO”皆为
boolean:
  - True
  - true
  - False
  - FALSE

其JSON如下:

{ boolean: [ true, true, false, false ] }

4.3 整数

支持二进制表示

int:
  - 666    # 十进制
  - 0b10   # 0b 前缀,二进制
  - 010    # 0 前缀,八进制
  - 0x10   # 0x 前缀,十六进制

其JSON如下:

{ int: [ 666, 2, 8, 16 ] }

4.4 浮点数

支持科学计数法

float:
  - 3.14
  - 6.8523015e+5
  - 6E3

其JSON如下:

{ float: [ 3.14, 685230.15, 6000 ] }

指数必须是整数

4.5 空值

nulls:
  - 
  - null
  - Null
  - NULL
  - ~

其JSON如下:

{ nulls: [ null, null, null, null, null ] }

4.6 时间戳

  • YAML 也支持 ISO 8601 格式的时间数据
date1: 2020-05-20 13:14:00.820+08:00  # +8表示该时间就是东八区的时间
date2: 2020-05-20 13:14:00.820  # 不加时区默认本初子母线的时间
date3: 2020-05-20 13:14:00.820+8

其JSON显示为:

{ date1: Wed May 20 2020 13:14:00 GMT+0800 (中国标准时间),
  date2: Wed May 20 2020 21:14:00 GMT+0800 (中国标准时间),
  date3: Wed May 20 2020 13:14:00 GMT+0800 (中国标准时间) }

5. 类型转换

  • YAML 支持使用严格类型标签!!(双感叹号+目标类型)来强制转换类型,下面是内置类型
    • !!int :整数类型
    • !!float :浮点类型
    • !!bool:布尔类型
    • !!str:字符串类型
    • !!binary:也是字符串类型
    • !!timestamp :日期时间类型
    • !!null:空值
    • !!set:集合
    • !!omap,!!pairs :键值列表或对象列表
    • !!seq:序列,也是列表
    • !!map:键值表
# YAML
a: !!float '666' # !! 为严格类型标签
b: '666' # 其实双引号也算是类型转换符
c: !!str 666 # 整数转为字符串
d: !!str 666.66 # 浮点数转为字符串
e: !!str true # 布尔值转为字符串
f: !!str yes # 布尔值转为字符串

JSON如下:

{ a: 666, b: '666', c: '666', d: '666.66', e: 'true', f: 'yes' }

6. 数据重用与合并

  • 为了保持内容的简洁,避免过多重复的定义,YAML 提供了由锚点标签“&”引用标签“*”组成的语法,利用这套语法可以快速引用相同的一些数据…

    # YAML
    a: &anchor # 设置锚点
      one: 1
      two: 2
      three: 3
    b: *anchor # 引用锚点
    

    JSON:

    { a: { one: 1, two: 2, three: 3 },
      b: { one: 1, two: 2, three: 3 } }
    

    锚点必须加在冒号后,值之前,然后用*符号可以解引用

  • 配合合并标签“<<”使用可以与任意数据进行合并,你可以把这套操作想象成面向对象语言中的继承

    # YAML
    human: &base # 添加名为 base 的锚点
        body: 1
        hair: 999
    singer:
        <<: *base # 引用 base 锚点,实例化时会自动展开
        skill: sing # 添加额外的属性
    programer:
        <<: *base # 引用 base 锚点,实例化时会自动展开
        hair: 6 # 覆写 base 中的属性
        skill: code # 添加额外的属性
    

    其JSON如下:

    { human: { body: 1, hair: 999 },
      singer: { body: 1, hair: 999, skill: 'sing' },
      programer: { body: 1, hair: 6, skill: 'code' } }
    

7. Python解析yaml——ruamel.yaml

  • 目前支持yaml 1.2,其他库只支持到yaml 1.1

例如yaml文件如下:

---
human: &human
  sex:student: &st
  no: !!int 100000
  name: ice
  <<: *human
  grade: 研一
  score: !!float 3.14
fruits:
  - apple
  - banana
  - orange

child: *st

matrix:
  -
    - 1
    - 2
    - 3
  -
    - 4
    - 5
    - 6
  -
    - 7
    - 8
    - 9
...

对应解析的Python代码如下:

from ruamel import yaml

with open("config.yaml", encoding="utf8") as f:
    config = yaml.load(f, Loader=yaml.RoundTripLoader)
    print(config["student"]["name"])  # ice
    print(config["student"]["score"])  # 3.14
    print(config["student"]["sex"])  # 男
    print(config["fruits"][1])  # banana
    print(config["child"]["sex"])  # 男
    print(config["matrix"])  # [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
  • 14
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值