1.8. 使用电子表格作为配置文件(DSL)

纯文本文件是程序员最喜欢使用的文件格式。

配置文件是用来对信息进行说明、存储的方式。 自有程序以来,配置文件也得到了很大的发展。

配置文件应该简洁,易于理解、编写,易于程序解析, 并且最好可以在不同的系统间交换。

由于纯文件文件本身并没有什么格式方面的约束, 为了用其作为配置文件,就需要设定一些约定, 以让程序能够识别关键词。

1.8.1. YAML 介绍

和GNU一样,YAML是一个递归着说“不”的名字。不同的是,GNU对UNIX说不,YAML说不的对象是XML。 YAML不是XML。

为什么不是XML呢?因为:

  • YAML的可读性好。

  • YAML和脚本语言的交互性好。

  • YAML使用实现语言的数据类型。

  • YAML有一个一致的信息模型。

  • YAML易于实现。

上面5条也就是XML不足的地方。同时,YAML也有XML的下列优点:

YAML可以基于流来处理;

YAML表达能力强,扩展性好。

总之,YAML试图用一种比XML更敏捷的方式,来完成XML所完成的任务。

更多的内容及规范参见http://www.yaml.org。

YAML语法规则:

http://www.ibm.com/developerworks/cn/xml/x-cn-yamlintro/
http://www.yaml.org/

语法

结构通过空格缩进来展示。列表里的项用”-“来代表,字典里的键值对用”:“分隔.

这几乎就是所有的语法了.

例如一般YAML文件扩展名为.yaml。比如:yaml_example.yaml

将yaml写成配置脚本test.yaml ,以下介绍如何读写yaml配置。

1.8.2. python中读取yaml配置文件

Python中读取yaml文件前需要安装pyyaml和导入yaml模块:

使用yaml需要安装的模块为pyyaml(pip3 install pyyaml);

导入的模块为yaml(import yaml

读取yaml文件数据

Python通过open方式读取文件数据,再通过load函数将数据转化为列表或字典;

>>> import yaml
>>> import os
>>> def get_yaml_data(yaml_file):
>>>     print("***获取yaml文件数据***")
>>>     file = open(yaml_file, 'r', encoding="utf-8")
>>>     file_data = file.read()
>>>     file.close()
>>>     print(file_data)
>>>     print("类型:", type(file_data))
>>>     print("***转化yaml数据为字典或列表***")
>>>     data = yaml.load(file_data)
>>>     print(data)
>>>     print("类型:", type(data))
>>>     return data
>>> current_path = os.path.abspath(".")
>>> yaml_path = os.path.join(current_path, "yaml_demo.yaml")
>>> get_yaml_data(yaml_path)
*获取yaml文件数据*
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连接,最后使用+代表时区
类型: <class 'str'>
*转化yaml数据为字典或列表*
{'boolean': [True, False], 'float': [3.14, 685230.15], 'int': [123, 685230], None: {'nodeName': 'node', 'parent': None}, 'string': ['哈哈', 'Hello world', 'newline newline2'], 'date': [datetime.date(2018, 2, 17)], 'datetime': [datetime.datetime(2018, 2, 17, 7, 2, 31)]}
类型: <class 'dict'>
/usr/lib/python3/dist-packages/ipykernel_launcher.py:16: YAMLLoadWarning: calling yaml.load() without Loader=... is deprecated, as the default Loader is unsafe. Please read https://msg.pyyaml.org/load for full details.
  app.launch_new_instance()
{'boolean': [True, False],
 'float': [3.14, 685230.15],
 'int': [123, 685230],
 None: {'nodeName': 'node', 'parent': None},
 'string': ['哈哈', 'Hello world', 'newline newline2'],
 'date': [datetime.date(2018, 2, 17)],
 'datetime': [datetime.datetime(2018, 2, 17, 7, 2, 31)]}

1.8.3. 将电子表格转换为 YAML

尽管 YAML 易于理解,也易于编写, 但是对于普通用户,仍然存在有诸多障碍。 要让普通用户写出无误的 YAML 文件,需要大量的培训与练习。

>>> import yaml
>>> from openpyxl import load_workbook
>>> value=[]
>>> table=[]
>>> wb = load_workbook('统计.xlsx')
>>> sheet = wb.get_sheet_by_name('Data4')
>>> for row in sheet.rows:
>>>     for cell in row:
>>>         value=[]
>>>         value.append(cell.value)
>>>     table.append(value)
>>> print(yaml.dump(table,default_flow_style=True))
[[Jerry], ['33'], ["u4EBAu4E8B"], ["u5973"]]