关键字 开发-03 渲染yaml文件中的变量

前言:引用渲染变量的模板有2个,一个是字符串模板,另一个是Jinja2模板

1. 字符串模板

1.1.1 通过字符串格式化方法进行渲染需要渲染的变量:

name = "dack"
age = 23

x = 'my name is %s, my age is %d' % (name, age)
print(x)

y = "my name is {}, my age is {}".format(name, age)
print(y)

z = f"my name is {name}, my age is {age}"
print(z)

1.1.2 template字符串模板

template 是字符串模板,用于替换字符串中的变量,是 string 的一个类引用变量有 2 种格式

  • $variable 使用 $变量名 引用变量
  • ${variable} 使用 ${变量名} 大括号包起来
# 第一种:$variable
from string import Template

tempTemplate_1 = Template("My name is $name, I like $fancy")
d = {"name": "dack", "fancy": "Python"}
print(tempTemplate_1.substitute(d))
# 结果: my name is dack, my age is 23

# 第二种:${variable}
tempTemplate_2 = Template("My name is ${name}, I like ${fancy}")
c = {"name": "dack", "fancy": "Python"}
print(tempTemplate_2.substitute(c))
# 结果: my name is dack, my age is 23

"""============================================================================"""

# 上面的方式只能严格的匹配变量,当字符串中有 $ 符号,不想匹配变量的时候,会报错
# safe_substitute 使用
from string import Template
tempTemplate_3 = Template("$My name is ${name}, I like ${fancy}")
e = {"name": "dack", "fancy": "Python"}
print(tempTemplate_3.substitute(e))
# 结果:error: KeyError: 'My'

# 忽略上面的error,使用Template里的safe_substitute方法,可以忽略匹配不到的变量
print(tempTemplate_3.safe_substitute(e))
# 结果:$My name is dack, I like Python
# 虽然字符串定义了多个变量,但是引用的时候只给了name这个值,也不影响运行,没给值的当普通字符串出来,这样就很完美了

1.1 yaml文件引用变量

test_login:
  name: 登录成功
  request:
    url: /api/v1/auth/login
    method: POST
    json:
      username: ${username}
      password: ${password}

test_login2:
  name: 登录失败
  request:
    url: /api/v1/auth/login
    method: POST
    json:
      username: "admin"
      password: "Admin@2233"

修改读取yaml文件的代码块:

# utils/read_file.py
import yaml
from string import Template
from pathlib import Path

def read_yaml(file_path: Path):
    """
    读取 yaml 数据,转 python 类型
    :param file_path:
    :return: dict
    """
    with open(file_path, 'r', encoding='utf-8') as fp:
        read_yml_data = fp.read() # 读到的是字符串
        temTemplate = Template(read_yml_data)
        yaml_data = temTemplate.safe_substitute({"username": "admin", "password": "Admin@22"})
        # str 转 python dict
        yaml_data = yaml.safe_load(yaml_data)
    return yaml_data


if __name__ == '__main__':
    file_path = Path(__file__).parent.parent.joinpath('data', 'login.yml')
    res = read_yaml(file_path)
    print(res)
    print(type(res))  # -->dict

运行结果:

2. jinja2模板

jinja2模板可以编写出可读性更好,更容易理解和维护的代码,并且使用范围非常广泛,python的模板库jinja2 功能是非常强大的,因此这里也顺便介绍下jinja2模板。
首先需要安装jinja2第三方库:pip install jinja2

2.1 jinja2常用的基本语法

  • {% %} 控制机构,可以用来写判断循环等语句
  • {{ }} 变量取值
  • {# #} 注释
    jinja2模板使用实例,如下代码块,看了一遍基本就会了。
from jinja2 import Template

# jinja2语法一:{{ }} 变量取值
t = Template("hello {{person}}")
msg = t.render(person="dack")
print(msg)
# 结果:hello dack

# jinja2语法二:{% %} 控制机构,可以用来写判断循环等语句
t1 = Template("My favorite numbers: {% for n in range(1, 5)%} {{n}} {% endfor %}")
msg1 = t1.render()
print(msg1)
# 结果:My favorite numbers:  1  2  3  4

t2 = Template("My name is {{name}} and I am {{age}}")
msg2 = t2.render(name="dack", age=22)
print(msg2)
# 结果:My name is dack and I am 22

t3 = Template("i have a dict {{mydict}}")
msg3 = t3.render(mydict={"a": 1, "b": 2})
print(msg3)
# 结果:i have a dict {'a': 1, 'b': 2}


"""对象取值"""
class Person:

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def get_name(self):
        return self.name

    def get_age(self):
        return self.age
p = Person("dack4", 33)
t4 = Template("my name is {{obj.name}}, my age is {{obj.age}}")
msg4 = t4.render(obj=p)
print(msg4)
# 结果:my name is dack4, my age is 33

"""字典取值"""
info = {
    "name": "dack_deng",
    "age": 44
}
t5 = Template("my name is {{my_info.name}} and i am {{my_info.age}}")
msg5 = t5.render(my_info=info)
print(msg5)
# 结果:my name is dack_deng and i am 44

"""修改jinja2的取值方式,从{{}}变成${}取值"""
t6 = Template("my name is ${my_info.name} and i am ${my_info.age}",
              variable_start_string='${', variable_end_string='}')
msg6 = t5.render(my_info=info)
print(msg6)
# 结果:my name is dack_deng and i am 44

2.2 Jinja2 渲染 yaml 文件变量

test_login:
  name: 登录成功
  request:
    url: /api/v1/auth/login
    method: POST
    json:
      username: ${username}
      password: ${password}

test_login2:
  name: 登录失败
  request:
    url: /api/v1/auth/login
    method: POST
    json:
      username: "admin"
      password: "Admin@2233"

接下来我们使用 jinja2 渲染 yaml 文件内容, 修改了jinja2 默认变量取值 {{ }} , 改成自定义的语法 ${ }

import yaml
from jinja2 import Template
from pathlib import Path

def read_yaml(file_path: Path):
    """
    读取 yaml 数据,转 python 类型
    :param file_path:
    :return: dict
    """
    with open(file_path, 'r', encoding='utf-8') as fp:
        read_yml_data = fp.read() # 读到的是字符串
        temTemplate = Template(read_yml_data, variable_start_string="${", variable_end_string="}")
        yaml_data = temTemplate.render({"username": "admin", "password": "Admin@22"})
        # yaml_data = temTemplate.safe_substitute({"username": "admin", "password": "Admin@22"})
        # str 转 python dict
        yaml_data = yaml.safe_load(yaml_data)
    return yaml_data

if __name__ == '__main__':
    file_path = Path(__file__).parent.parent.joinpath('data', 'login.yml')
    res = read_yaml(file_path)
    print(res.items())
    print(type(res))  # -->dict

运行后,如下图所示,yaml文件使用jinja2模板渲染数据成功。

使用jinja2模板成功后,接下来考虑,如何使用jinja2模板动态渲染变量。

posted @ 2023-11-24 18:14  dack_deng  阅读(332)  评论(0编辑  收藏  举报