Python之-操作yaml

这篇具有很好参考价值的文章主要介绍了Python之-操作yaml。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

操作yaml文件

1.yaml介绍

yaml:Yet Another Markup Language的缩写。Yaml是专门用来写配置文件的语言,非常简洁和强大,远比json格式方便。

  • Python搭建yaml环境

pip install PyYaml

pip install --ignore-installed PyYAML

  • yaml的语法规则

大小写敏感   

使用缩进表示层级关系   

缩进时不允许使用Tab键,只允许使用空格。   

缩进的空格数目不重要,只要相同层级的元素左侧对齐即可   

使用#表示注释    字符串可以不用引号标注

  • yaml的样式

1. 对象:键值对的集合(字典形式)

键值对用冒号”:” 间隔,冒号之间需要用空格分隔

如:

phone: 151xxxxxxxx addr: xx路xx号

得到结果:

{“phone”:”151xxxxxxxx”,”addr”:”xx路xx号”}

2. 数组:列表的形式

数组前需要有短横杠”-”符号,符号与值之间需要用空格分隔

如:

- value1 - value2

得到结果:

[“value1”,”value2”]

3. 特殊类型

字符串默认不使用引号表示。但是字符串之中包含空格或特殊字符,需要放在引号之中

str: '内容: 字符串'

None值可用null 或 ~ 符号表示

单引号和双引号都可以使用,双引号不会对特殊字符转义。

s1: '内容\n字符串' s2: "内容\n字符串"

其他内容可参考:https://www.ruanyifeng.com/blog/2016/07/yaml.html?f=tt

4.多个yaml在一个文档中,使用---分割

yaml文件示例

---
student:
  - name: lucy,
    age: 18
    class: 19
    grade: { English: 98,Math: 50,Art: 33 }
  - name: momo,
    age: 33
    class: 20
    grade: { English: 55,Math: 100,Art: 98 }
---
reqesttdata:
  - { shouji: 13456755448,appkey: 0c818521d38759e1 }
  - { shouji: 13456755449,appkey: 0c818521d38759e1 }
  - { shouji: 13456755450,appkey: 0c818521d38759e1 }

读取方法示例

def get_more_than_one_yaml_for_one_file():
    f = open(file=data_file_path1,mode="r")
    data = yaml.safe_load_all(f)#读取一个yaml文件中多个文档需要使用yaml.load_all())
    return data
test_data = get_more_than_one_yaml_for_one_file()
for i in test_data:
    print(i)
    """
    结果是:
    {'student': [{'name': 'lucy,', 'age': 18, 'class': 19, 'grade': {'English': 98, 'Math': 50, 'Art': 33}}, {'name': 'momo,', 'age': 33, 'class': 20, 'grade': {'English': 55, 'Math': 100, 'Art': 98}}]}
{'reqesttdata': [{'shouji': 13456755448, 'appkey': '0c818521d38759e1'}, {'shouji': 13456755449, 'appkey': '0c818521d38759e1'}, {'shouji': 13456755450, 'appkey': '0c818521d38759e1'}]}
    """
print(list(get_more_than_one_yaml_for_one_file())) #通过将generator转换为列表来操作列表
"""结果是
[{'student': [{'name': 'lucy,', 'age': 18, 'class': 19, 'grade': {'English': 98, 'Math': 50, 'Art': 33}}, {'name': 'momo,', 'age': 33, 'class': 20, 'grade': {'English': 55, 'Math': 100, 'Art': 98}}]}, {'reqesttdata': [{'shouji': 13456755448, 'appkey': '0c818521d38759e1'}, {'shouji': 13456755449, 'appkey': '0c818521d38759e1'}, {'shouji': 13456755450, 'appkey': '0c818521d38759e1'}]}]
"""

此外有个注意点,如果使用with open去操作一个一个yaml文件中多个文档的时候,会报异常:ValueError: I/O operation on closed file.

比如

def get_more_than_one_yaml_for_one_file_1():
    with open(file=data_file_path1,mode='r') as f:
        data = yaml.safe_load_all(f)
        return data
a = get_more_than_one_yaml_for_one_file_1()
print(a)#生成了generator
for i in a:
    print(i)
    # 循环拿generator的值就会报错ValueError: I/O operation on closed file.,
    # 我猜是因为with open操作完文件流自动关闭了
    # 但是为什么是这样,没有找到原因,如果知道原因麻烦评论留言

2.读取yaml文件

step1:导入yaml包

import yaml

step2:打开目标文件,读取内容(以字典内容嵌套的格式为例)

打开目标文件的时候,要找yaml文件所在目录

yaml的内容

python yaml,Pytest,python,pytest,python

student:
   - name: lucy,
     age: 18
     class: 19
     grade: { English: 98,Math: 50,Art: 33 }
   - name: momo,
     age: 33
     class: 20
     grade: { English: 55,Math: 100,Art: 98 }

1、为了全局使用考虑,一般在项目的根目录下面,写一个方法,获取跟目录的路径

conftest.py 在项目的根目录下

import os
def get_project_path():
    return os.path.dirname(os.path.abspath(__file__))
PROJECT_PATH = get_project_path()
print(PROJECT_PATH)

结果是:

python yaml,Pytest,python,pytest,python

2. 然后在读取的时候,先导入这个PROJECT_PATH,拼接yaml文件所在的路径

from conftest import PROJECT_PATH
import os
data_file_path = PROJECT_PATH + "\data\student.yaml"
data_file_path1 = os.path.join(PROJECT_PATH,"data","student.yaml")
print("data_file_path是: ",data_file_path)
print("data_file_path1是:",data_file_path1)
# data_file_path 和data_file_path1 是同样的结果

结果是

python yaml,Pytest,python,pytest,python

3.读取yaml的内容

import os
import yaml
from conftest import PROJECT_PATH
data_file_path1 = os.path.join(PROJECT_PATH,"data","student.yaml")
def get_yaml_data():
    with open(file=data_file_path1, mode='r') as f:
        data = yaml.safe_load(f)
        return data
students_info = get_yaml_data()
print(students_info)

结果是

{'student': 
    [
    	{'name': 'lucy,', 'age': 18, 'class': 19, 'grade': {'English': 98, 'Math': 50, 'Art': 33}}, 
     	{'name': 'momo,', 'age': 33, 'class': 20, 'grade': {'English': 55, 'Math': 100, 'Art': 98}}
    ]
}

如果要获取student列表,可通过key去拿值,然后获取相关的内容

students_info["student"]

3.yaml文件的写入

写入是使用yaml.dump()来完成的,要传入两个参数,一个是写入的内容,一个是文件流

import os
import yaml
from conftest import PROJECT_PATH
data_file_path2 = os.path.join(PROJECT_PATH, "data", "student1.yaml")
data = {'reqesttdata': [{'shouji': 13456755448, 'appkey': '0c818521d38759e1'},
                        {'shouji': 13456755449, 'appkey': '0c818521d38759e1'},
                        {'shouji': 13456755450, 'appkey': '0c818521d38759e1'}]}

def write_yaml(data,file_path):
    with open(file=file_path,mode='w',encoding='utf8') as f:
        yaml.dump(data,f)

def read_yaml(data,file_path):
    write_yaml(data,file_path)
    f = open(file=file_path, mode='r', encoding='utf8')
    return yaml.safe_load(f)
print(read_yaml(data,data_file_path2))

运行结果是:成功写入

python yaml,Pytest,python,pytest,python

注意“w”和“a”的区别

with open(yaml_path, "w", encoding="utf-8")   这里w是将文件数据清除后重新写入
with open(yaml_path, "a", encoding="utf-8")   这里a是追加写入

现在数据已经可以正常写入了,如果想要修改数据怎么办呢?也很简单,大体思路就是 读取-->修改-->重写

yaml文件内容

reqesttdata:
- appkey: 0c818521d38759e1
  shouji: '13456755448'
- appkey: 0c818521d38759e1
  shouji: '13456755449'
- appkey: 0c818521d38759e1
  shouji: '13456755450'
data_file_path2 = os.path.join(PROJECT_PATH, "data", "student2.yaml")
data = {'reqesttdata': [{'shouji': "13456755448", 'appkey': '0c818521d38759e1'},
                        {'shouji': "13456755449", 'appkey': '0c818521d38759e1'},
                        {'shouji': "13456755450", 'appkey': '0c818521d38759e1'}]}

def write_yaml(data, file_path):
    """
    写入yaml文件,需要写入的内容和写入的路径
    :param data:
    :param file_path:
    :return:
    """
    with open(file=file_path, mode='w', encoding='utf8') as f:
        yaml.dump(data, f)

def read_yaml(file_path):
    """
    读取yaml文件,需要读取的路径参数file_path
    :param file_path:
    :return:
    """
    f = open(file=file_path, mode='r', encoding='utf8')
    return yaml.safe_load(f)


# 修改shouji=13456755448 为15091757825
def update(k, old_v, new_v):
    """
    修改yaml中列表嵌套字典的值,通过键值对去修改
    :param k:
    :param old_v:
    :param new_v:
    :return:
    """
    yam_data = read_yaml(data_file_path2)#先读取内容
    #yaml文件是字典嵌套列表,所以要通过 yam_data["reqesttdata"]拿到里面的字典列表
    new_data_list = []
    for item in yam_data["reqesttdata"]:
        for i in item:
            # 然后判断对应的键值对是否存在{'shouji': '13456755448'}
            if i==k and item[i]==old_v:
                item[i]=new_v
        # 如果存在修改值,放到修的列表中
        new_data_list.append(item)
    #把新的列表再赋值给字典yam_data["reqesttdata"]
    yam_data["reqesttdata"]=new_data_list
    #调用写入yaml的方法重新写入文件
    write_yaml(yam_data,data_file_path2)
#先写入才能读取
write_yaml(data,data_file_path2)

update("shouji", "13456755448", "15091757825")
print(read_yaml(data_file_path2))

运行结果

python yaml,Pytest,python,pytest,python

4.yaml文件的引用

(1)内部引用

锚点&和引用*对于重复的数据,可以单独写到yaml文件的开头位置,其它的地方用到的可以用*引用

python yaml,Pytest,python,pytest,python

读取

import os
import pprint
import yaml
from conftest import PROJECT_PATH
def read_yaml(file_path):
    """
    读取yaml文件,需要读取的路径参数file_path
    :param file_path:
    :return:
    """
    f = open(file=file_path, mode='r', encoding='utf8')
    return yaml.safe_load(f)
data_file_path3 = os.path.join(PROJECT_PATH, "data", "test_yaml_refer.yaml")
yamldata = read_yaml(data_file_path3)
#pprint用于美化打印的字典
pprint.pprint(yamldata)

读取结果

python yaml,Pytest,python,pytest,python

(2)外部引用

-未理解,需要找时间进一步学习

使用关键字:!include

python yaml,Pytest,python,pytest,python

python yaml,Pytest,python,pytest,python

4.yaml的应用场景

自动化测试框架的配置文件或用例文件

用例文件和pytest结合使用示例:

import configparser
import yaml
from conftest import PROJECT_PATH

ini_file = PROJECT_PATH + "\config\setting.ini"
yaml_file = PROJECT_PATH + "\data\yaml_test_data.yaml"


class GetData:
    # ini_file = PROJECT_PATH + "\config\setting.ini"
    # yaml_file = PROJECT_PATH + "\data\yaml_test_data.yaml"
    def __init__(self):
        self.ini_file = ini_file
        self.yaml_file = yaml_file

    def get_ini_data(self):
        con = configparser.ConfigParser()
        con.read(self.ini_file, encoding="utf8")
        return con

    def get_yaml_data(self):
        with open(self.yaml_file, encoding="utf8") as f:
            data = yaml.safe_load(f)
            return data
my_data = GetData()
get_ini_data = my_data.get_ini_data()
get_yaml_data = my_data.get_yaml_data()

setting.ini

[host] api_sit_url=https://api.binstd.com

yaml_test_data.yaml

reqesttdata:
   - {shouji: 13456755448,appkey: 0c818521d38759e1}
   - {shouji: 13456755449,appkey: 0c818521d38759e1}
   - {shouji: 13456755450,appkey: 0c818521d38759e1}

testcase代码

import requests
from util.read_data import get_ini_data,get_yaml_data
import pytest
url = get_ini_data["host"]["api_sit_url"]
request_data = get_yaml_data["reqesttdata"]

@pytest.mark.parametrize("testdata",request_data)
def test_mobie(testdata):
    res = requests.get(url=url+"/shouji/query",params=testdata)
    assert res.status_code==200
    assert res.json()["result"]["shouji"]=="13456755448"
    assert res.json()["result"]["province"]=="浙江"
    assert res.json()["result"]["city"]=="杭州"
    assert res.json()["result"]["company"]=="中国移动"
    assert res.json()["result"]["areacode"]=="0571"

执行结果

python yaml,Pytest,python,pytest,python

python yaml,Pytest,python,pytest,python文章来源地址https://www.toymoban.com/news/detail-767705.html

到了这里,关于Python之-操作yaml的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 接口测试框架pytest+yaml之yaml文件的相互引用

    在写测试框架的一篇文章中提到过(python接口测试框架选择之pytest+yaml+Allure_亲爱的阿满啊的博客-CSDN博客_pytest yaml),yaml可以用来编写测试数据,yaml文件间的互相引用使测试数据的编写更灵活。比如接口之间会存在一些共性,存在上传的字段相同,这些相同的字段可以写在ya

    2023年04月08日
    浏览(40)
  • pycharm中安装playwright、pytest、yaml、Allure及相关配置

    本次配置主要是为了搭建环境,playwright+pytest+yaml+allure,用于做UI测试; 1.首先安装pycharm,并且破解成功; 2.修改pip的配置(目的把下载源设置成国内的) 终端执行命令: pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple 补充: - 清华:https://pypi.tuna.tsinghua.edu.cn/simple

    2024年02月16日
    浏览(51)
  • pytest + yaml 框架 -60.git+jenkins+allure+钉钉通知反馈

    当我们自动化用例写完后,接下来就是如何运行用例,生成报告以及反馈通知了。 如果你们公司已经有jenkins了,那么直接集成到jenkins上构建你的自动化任务是非常方便的。 第一步,将写好的自动化用例,上传到本公司的git仓库。 在jenkins上创建一个自由风格的项目 源码管理

    2024年02月04日
    浏览(113)
  • Python测试框架 Pytest —— mock使用(pytest-mock)

    安装:pip install pytest-mock 这里的mock和unittest的mock基本上都是一样的,唯一的区别在于pytest.mock需要导入mock对象的详细路径。 先将需要模拟的天气接口,以及需要模拟的场景的代码写好,然后在进行遵循pytest的用例规范进行书写关于mock的测试用例 通过上述代码,提供pytest中

    2024年02月09日
    浏览(46)
  • Python+Pytest压力测试

    在现代Web应用程序中,性能是至关重要的。为了确保应用程序能够在高负载下正常运行,我们需要进行性能测试。 今天,应小伙伴的提问, 老向老师来写一个Pytest进行压力测试的简单案例。 这个案例的测试网站我们就隐藏了,不过网站的基本情况是: 阿里框架:FastAdmin.n

    2024年02月12日
    浏览(93)
  • [python] pytest

    在写一个项目前, 可以先编写测试模块 测试模块中包含了一个个最小的功能 当每一个功能都完善正确时 再将这些功能转换成项目运行的功能 多个项目运行的功能就组成了一个模块 多个模块就组成了一个项目服务 pytest 是一个 Python 测试框架,它提供了简单易用的语法和丰富

    2024年02月07日
    浏览(73)
  • python之pytest

    pytest是python的一种单元测试框架,同自带的unittest测试框架类似,相比起来,pytest更简单。 特点: 1.入门简单,文档丰富 2.支持简单的单元测试和复杂的功能测试 3.支持参数化 4.执行测试过程中可以将某些测试跳过,或者对某些预期失败的case标记成失败 5.支持重复执行失败的

    2024年02月05日
    浏览(54)
  • Python模块—Pytest模块

    1. args参数 参数 作用 -v 详细输出测试信息。 -q 简要输出测试信息。 -s 输出测试用例中的print语句。 -x 遇到失败用例时立即停止测试。 -k 根据条件指定用例去测试,如:‘-k’ ,‘TestCase and not test_case_1’(可指定类名函数名) -m 根据修饰器指定用例去测试,如:‘-m’ , ‘

    2024年02月14日
    浏览(39)
  • Python —— pytest框架

    1、搭建自动化框架的思路与流程 1、搭建自动化测试框架的思路和流程,任意测试手段流程都是一致的:手工测试、自动化测试、工具测试 手工测试:熟悉业务 —— 写用例 —— 执行用例并记录结果 —— 生成测试报告 自动化测试:熟悉业务 —— 写自动化用例(来自于手工

    2024年04月17日
    浏览(35)
  • 10 python pytest

    项目里面新建 xxx.txt文件 执行pip install -r xxx.txt一次性安装所有插件 pytest-html 生成html格式的自动化测试报告 pytest-xdist 测试用例分布式执行,多cpu分发 pytest-ordering 用于改变测试用例的执行顺序 pytest-rerunfailures 用于失败后重跑 pytest-pytest 用于生成美观的测试报告 1,模块必须以

    2024年02月17日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包