Python使用第三方库之【yaml】

【环境】

  • Ubuntu 16.04 LTS
  • Python

【正文】

1、入门基础

Python生态中成千上万的第三方库,yaml就是其中之一。

1.1 概念

YAML is a human friendly data serialization standard for all programming languages.
译作 YAML是一个对所有编程语言都很友好的数据序列化标准

YAML,是YAML Ain’t Markup Language的缩写,译作 YAML不是一种标记语言

但为了强调该语言以数据为中心,而不是以标记语言为重点,而用返璞词重新命名。它是一种直观的能够被电脑识别的数据序列化格式,是一种可读性高且容易被人类阅读、容易和脚本语言(不仅仅是Python)交互,用于表达资料序列编程语言
YAML语言的本质是 一种通用的数据串行化格式。

Clark Evans在2001年首次发表了YAML语言,并跟其他几位作者共同设计。目前已有数种编程语言和脚步语言能够解析这种语言。

PS:
1)ain’t = am not prep (不是)
也可用作are not、is not、has not、will not、have not的缩略词。多用作非正式的口语。
2)返璞词,是人类语言的发展过程中某些词语经过演变词义产生扩大或变化,为了加以区别产生的新词。通常会对原有的名词加上定语来修饰。参考百科
3)关于 序列化(含义、为什么需要序列化等等),参考大佬博客

1.2 适用场景

  • 在脚步语言中使用,实现简单,解析成本低;
  • 序列化;
  • 编程时写配置文件,比xml快,比ini文档功能更强。YAML是专门用于写配置文件的语言,非常简洁和强大,远比JSON格式方便。

1.3 YAML语法

基本语法规则

  1. 大小写敏感;
  2. 使用缩进表示层级关系;
  3. 缩进时不允许使用Tab键,只允许使用空格;
  4. 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可(一般2个 或4个空格);
  5. # 表示注释当前行。

YAML支持的数据结构有3种

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

其中:
对象
使用冒号代表,格式为 key: value。冒号后须加一个空格。

使用缩进表示层级关系,如下:

key:
  child_key1: value1
  child-key2: value2

YAML还支持流式(flow)语法表示对象,上例可写成:

key: {child_key1: value1, child_key2: value2}

这在Python中是 字典嵌套字典,是这么写的:

"key": {
        "child_key1":"value1",
        "child_key2":"value2"
       }

较为复杂的对象格式,可使用 一个问号 加一个空格代表一个复杂的key,配合一个冒号加一个空格 代表一个value:

? 
  - complex_key1
  - complex_key2
: 
  - complex_value1
  - complex_value2

上述表示:对象的属性是一个数组[complex_key1, complex_key2],其对应的值也是一个数组[complex_value1, complex_value2]

数组
使用一个短横线 加一个空格代表一个数组项:

hobby:
  - python
  - test

也可这样写:

- 
  - python
  - test

可简单理解为:[[python, test]]

再看一个相对复杂的例子:

role:
  - 
    id: 1
    name: developer
    auth: dev
  - 
    id: 2
    name: tester
    auth: test 

可理解为:role属性是一个数组,每个数组元素又是由idnameauth 3个属性构成。
用流式(flow)的方式表示如下:

role: [{id: 1, name: developer, auth: dev}, {id: 2, name: tester, auth: test}]

对象和数组 可结合使用,形成复合结构。

languages:
 - Ruby
 - Perl
 - Python 
websites:
 YAML: yaml.org 
 Ruby: ruby-lang.org 
 Python: python.org 
 Perl: use.perl.org

纯量

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

YAML提供了多种常量结构:整数、浮点数、字符串、NULL、日期、布尔值、时间。

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

还有一些特殊符号

--- YAML可在同一个文件中,使用---表示一个文档的开始

server: 
  address: 192.168.1.100
---
spring: 
  profiles: development
  server: 
    address: 127.0.0.1
---
spring:
  profiles: production
  server: 
    address: 192.168.1.120

上述例子定义两个profile,一个development、一个production。
也可以用 ---分割不同的内容,比如记录日志:

---
Time: 2018-12-29T19:09:30+08:00
User: ed
Warning:
  This is an error message for the log file.
---
Time: 2018-12-29T19:11:45+08:00
User: ed
Warning:
  A slightly different error message.

...---配合使用,在一个配置文件中代表一个的结束:

---
time: 19:13:09
player: Tim
action: strike
...
---
time: 20:14:45
player: Lily
action: grand
...

此例相当于在一个yaml文件中连续写了两个yaml配置项。

!! YAML中使用!!做类型强行转换:

string:
  - !!str 123456
  - !!str true

相当于将数字和布尔类型强转为字符串(允许转换的类型还有很多)。

> 在字符串中折叠换行;| 保留换行。这两个符号是YAML中字符串经常使用的符号,例:

acomplistment: >
  Mark set a major league
  home run record in 1998.
status: |
  65 Home Runs
  0.278 Batting Average

accomplistment的结果为:

accomplistment=Mark set a major league home run record in 1998.

status的结果为:

status=65 Home Runs
 0.278 Batting Average

⑤ 引用。重复的内容在YAML中可使用&来完成锚点定义,用*来完成锚点引用,例:

hr: 
  - Mark McGwire
  - &SS Sammy Sosa
rbi: 
  - *SS
  - Ken Griffey

hr中,使用&SSSammy Sosa设置了一个锚点(引用),名称为SS;在rbi中,使用*SS完成了锚点使用。结果是:

{rbi=[Mark McGwire, Ken Griffey], hr=[Mark McGwire, Sammy Sosa]}

也可以这样定义:

SS: &SS Sammy Sosa
hr:
 - Mark McGwire
 - *SS
rbi:
 - *SS 
 - Ken Griffey

还可以用锚点定义更复杂的内容:

default: &default
    - Mark McGwire
    - Sammy Sosa
hr: *default

hr相当于引用default数组。不过,hr: *default须写在同一行。

⑥ 合并内容。主要是和锚点配合使用,可将一个锚点内容直接合并到一个对象中。例:

merge:
  - &CENTER { x: 1, y: 2 }
  - &LEFT { x: 0, y: 2 }
  - &BIG { r: 10 }
  - &SMALL { r: 1 }
  
sample1: 
    <<: *CENTER
    r: 10
    
sample2:
    << : [ *CENTER, *BIG ]
    other: haha
    
sample3:
    << : [ *CENTER, *BIG ]
    r: 100

merge中,定义了四个锚点,分别在sample中使用。

sample1中,<<: *CENTER意思是引用{x: 1,y: 2},并且合并到sample1中,那么合并的结果为:sample1={r=10, y=2, x=1}

sample2中,<<: [*CENTER, *BIG] 意思是联合引用{x: 1,y: 2}{r: 10},并且合并到sample2中,那么合并的结果为:sample2={other=haha, x=1, y=2, r=10}

sample3中,引入了*CENTER, *BIG,还使用了r: 100覆盖了引入的r: 10,所以sample3值为:sample3={r=100, y=2, x=1}

有了合并,我们就可以在配置中,把相同的基础配置抽取出来,在不同的子配置中合并引用即可。

2、实战

2.1 安装yaml

安装很简单,在此省略。
注意包名是 pyyaml,但导入是yaml。

2.2 Python使用yaml

以 【用Python 读取yaml文件(后缀可为 .yml.yaml)】为例:先用open方法读取文件数据,再通过load方法转成字典(load方法跟json的load是相似的)

在同一个文件夹下,编写yaml文件,名为 cfg.yml,内容如下:

nb:
  user: admin
  psw: 123456

编写读取yaml文件的.py文件,名为 readyml.py,内容如下:

import yaml
import os

curPath = os.path.dirname(os.path.realpath(__file__)) # 获取当前脚本所在文件夹路径
ymlPath = os.path.join(curPath, "cfg.yml") # 获取yaml文件路径

# 用open方法打开直接读取
f = open(ymlPath, 'r')
cfg = f.read()
print(type(cfg)) # 读取的结果是 字符串
print(cfg)

d = yaml.load(cfg) # 用load方法转字典
print(d)
print(type(d))

a = {'name': 'chenchen',
	'race': 'Human',
	'traits': ['Two_Hand', 'Two_Eye']
}
ret = yaml.dump(a)
print(ret)
print(type(ret))

运行结果:

chenchen@chenchen-ubuntu:/usr/ccdocs/test$ python readyml.py
<type 'str'>
nb:
  user: admin
  psw: 123456

{'nb': {'user': 'admin', 'psw': 123456}}
<type 'dict'>
name: chenchen
race: Human
traits: [Two_Hand, Two_Eye]

<type 'str'>

文件结构如下:

chenchen@chenchen-ubuntu:/usr/ccdocs/test$ tree
.
├── cfg.yml
└── readyml.py

0 directories, 2 files

其中,最重要的两个方法:

  • load(),解析yaml文档,返回一个Python对象;
  • load_all(),如果是string或文件包含几块yaml文档,可用该方法来解析全部的文档,生成一个迭代器;
  • dump(),将一个Python对象生成为一个yaml文档;
  • dump_all(),将多个段输出到一个yaml文档中。

参考文档:
1、yaml for python 源码
2、官网
3、YAML Version 1.2 英文文档

  • 6
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值