在开发过程中,我们常常会用到一些固定参数或常量。对于这些常用的部分,我们往往会将其写到一个固定文件中,避免在不同的模块代码中重复出现,以保持核心代码整洁。这个固定文件我们可以直接写成一个.py文件,如settings.py或config.py,这样的好处是能够在同一工程下通过import来导入当中的部分参数或变量。
但如果我们需要在其他非Python的平台进行配置文件共享时,写成单个.py文件就不是一个很好的选择。这时我们就应该选择通用的配置文件格式类型存储这些固定的参数或变量。目前常用且流行的配置文件格式类型主要有ini、JSON、yaml等,如表4-20所示,我们可以通过标准库或第三方库来解析这些格式类型的配置文件。
表4-20 配置文件格式类型
yaml基础
yaml的基本语法规则如下:
-
大小写敏感;
-
使用缩进表示层级关系;
-
缩进时不允许使用Tab键,只允许使用空格;
-
缩进的空格数目不重要,只要相同层级的元素左侧对齐即可;
-
#表示注释,从这个字符一直到行尾,都会被解释器忽略;
-
键值中间要有空格,即键后面的冒号必须加空格来分开键和值。
yaml支持的数据结构主要有如下3种。
(1)对象:键值对的集合,如映射、哈希和字典。
(2)数组:一组按次序排列的值,如序列、列表。
(3)纯量:单个的、不可再分的值,如字符串、布尔值、整数、浮点数、Null、时间和日期。
对象键值对使用冒号结构表示为“key: value”,冒号后面要加一个空格。我们可以使用key:{child-key1: value1, child-key2: value2, ...},可以使用缩进表示层级关系。
数组由一组连词线开头的行构成。数组前加“-”符号,符号与值之间需用空格分隔:
key:
child-key1: value1
child-key2: value2
以“-”开头的行构成一个数组:
- A
- B
- C
yaml支持多维数组,可以使用行内表示:
key: [value1, value2, ...]
一个相对复杂的示例如下:
companies:
-
id: 1
name: company1
price: 200W
-
id: 2
name: company2
price: 500W
其中companies属性是一个数组,每一个数组元素由id、name、price这3个属性构成。
另外,数组和对象可以构成复合结构,示例如下:
languages:
- Ruby
- Perl
- Python
websites:
YAML: yaml.org
Ruby: ruby-lang.org
Python: python.org
Perl: use.perl.org
转换为JSON示例如下:
{
languages: [ 'Ruby', 'Perl', 'Python'],
websites: {
YAML: 'yaml.org',
Ruby: 'ruby-lang.org',
Python: 'python.org',
Perl: 'use.perl.org'
}
}
纯量是最基本的、不可再分的值,使用纯量示例如下:
# 输出一个字典,其中value包括所有基本类型
str: "Hello World!"
int: 110
float: 3.141
boolean: true # or false
None: null # 也可以用~号来表示null
time: 2016-09-22t11:43:30.20+08:00
date: 2016-09-22
该示例实际输出结果如下:
{'str': 'Hello World!', 'int': 110, 'float': 3.141, 'boolean': True, 'None': None, 'time':
datetime.datetime(2016, 9, 22, 3, 43, 30, 200000), 'date': datetime.date(2016, 9, 22)}
注意
如果字符串没有空格或特殊字符,则不需要加引号。这里要注意单引号和双引号的区别,在Python中,单引号中的特殊字符会被转义,即原样输出字符,而双引号中的特殊字符不会被转义,即输出特殊字符应有的作用,例如str1: 'Hello\nWorld'和str2: "Hello\nWorld",单引号中的\n原样输出,双引号中的\n输出回车。
在刚了解或刚开始使用时,我们可能对yaml格式掌握不熟练,容易出现格式错误,可以利用yaml格式校验的在线网站,校验我们写的yaml文件格式是否正确。
PyYAML库
在Python中读取yaml配置文件,需要用到第三方库PyYAML。安装PyYAML库的命令为pip install pyYAML。
下面针对PyYAML库,简要讲解读写操作。
(1)创建一个yaml文件config.yml,内容如下:
name: Tom Smith
age: 37
spouse:
name: Jane Smith
age: 25
children:
- name: Jimmy Smith
age: 15
- name1: Jenny Smith
age1: 12
(2)利用safe_load方法返回一个对象:
import yaml
# 通过open方式读取文件数据
file = open('config.yml', 'r', encoding="utf-8")
# 再通过safe_load函数将数据转化为列表或字典
data = yaml.safe_load(file)
print(data)
输出结果如下:
{'name': 'Tom Smith', 'age': 37, 'spouse': {'name': 'Jane Smith', 'age': 25}, 'children':
[{'name': 'Jimmy Smith', 'age': 15}, {'name1': 'Jenny Smith', 'age1': 12}]}
(3)利用load_all方法生成一个迭代器。如果string或文件包含几块yaml文档,我们可以使用yaml.load_all来解析全部的文档。
import yaml
# 通过open方法读取文件数据
file = open('config.yml', 'r', encoding="utf-8")
y = yaml.load_all(file, Loader=yaml.FullLoader)
for data in y:
print(data)
输出结果如下:
{'name': 'James', 'age': 20}
{'name': 'Lily', 'age': 19}
(4)利用yaml.dump方法将一个Python对象转换为yaml文档:
import yaml
aproject = {'name': 'Silenthand Olleander',
'race': 'Human',
'traits': ['ONE_HAND', 'ONE_EYE']
}
print(yaml.dump(aproject))
输出结果如下:
name: Silenthand Olleander
race: Human
traits:
- ONE_HAND
- ONE_EYE
若yaml.dump方法的第二个参数不是空值,那么第二个参数一定要是一个打开的文本文件或二进制文件,yaml.dump方法会把生成的yaml文档写入文件,示例如下:
import yaml
aproject = {'name': 'Silenthand Olleander',
'race': 'Human',
'traits': ['ONE_HAND', 'ONE_EYE']
}
f = open(r'config.yml','w')
print(yaml.dump(aproject,f))
(5)利用yaml.dump_all方法将多个段输出到一个文件中:
import yaml
obj1 = {"name": "James", "age": 20}
obj2 = ["Lily", 19]
with open(r'config.yml', 'w') as f:
yaml.dump_all([obj1, obj2], f)
输出到文件config.yml,该文件里的内容如下:
age: 20
name: James
---
- Lily
- 19
封装示例
我们可以将yaml操作封装成一个公共类,这样在后续配置文件引用中直接调用,完整的封装代码示例如代码清单4-10所示,主要是封装了yaml配置文件的读取和写入。
# -*- coding: utf-8 -*-
# @Time : 2022/2/25 10:29 上午
# @Project : yamlDemo
# @File : yamlUtil.py
# @Author : hutong
# @Describe: 微信公众号:伤心的辣条
# @Version: Python3.9.8
import yaml
class YamlHandler( ):
def __init__(self,file):
self.file = file
def read_yaml(self,encoding='utf-8'):
"""读取yaml数据"""
with open(self.file, encoding=encoding) as f:
return yaml.load(f.read(), Loader=yaml.FullLoader)
def write_yaml(self, data, encoding='utf-8'):
"""向yaml文件写入数据"""
with open(self.file, encoding=encoding, mode='w') as f:
return yaml.dump(data, stream=f, allow_unicode=True)
if __name__ == '__main__':
data = {
"user":{
"username": "vivi",
"password": "123456"
}
}
# 读取config.yaml配置文件数据
read_data = YamlHandler('config.yaml').read_yaml()
# 将data数据写入config1.yaml配置文件
write_data = YamlHandler('config1.yaml').write_yaml(data)
代码清单4-10 yamlUtil
最后:下方这份完整的软件测试视频教程已经整理上传完成,需要的朋友们可以自行领取【保100%免费】
软件测试面试文档
我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。