Python处理接口数据,这个函数太香了

image1

Python处理接口数据

接口数据通常是JSON格式,Python处理起来并不轻松。

方法一,json文件。额外编写代码读取文件,接口参数很多,文件变多,难维护。

方法二,字典。JSON可以直接粘贴到代码中,Python认作字典,但语法有差异,JSON的语法是true/false/null,Python的语法是True/False/None,不兼容。

这两种方法都有共同的缺点,需要编写表达式来定位某个节点。

比如:body["a"][0]["x"]["m"]

字符串与占位符

占位符是一种很常见的文本替换技术,在任何编程语言中都有广泛应用。

Python语法有个很特别的字符串,三引号字符串:

test_json = """
{
 "bool": true,
  "x": null,
  "customerId": "123456",
  "items": [
    {
      "productId": "987654",
      "quantity": 2,
      "price": 199.99
    }
  ],
  "shippingAddress": {
    "recipientName": "张三",
    "streetAddress": "北京市朝阳区某街道123号",
    "city": "北京",
    "state": "北京",
    "postalCode": "100000",
    "country": "中国"
  },
  "paymentMethod": {
    "type": "CreditCard",
    "cardNumber": "4111111111111111",
    "expiryDate": "12/25",
    "cvv": "123"
  },
  "orderNotes": "请尽快发货,谢谢!"
}
"""

基本思路是,把JSON写在三引号字符串中,这能保留原生JSON格式,就像很多测试平台的做法一样,然后再通过占位符,直接替换其中的节点值。占位符不用编写表达式定位节点,在JSON字符串标记即可。

思路有了,怎么写呢?Python没有现成的函数,没关系,自己写一个。

tep3函数v()

tep3的新特性,函数v()正是用来解决这个问题的。

实际效果:

普通字符串

## 以前
domain = "https://dongfanger.github.io"
url = domain + "/blog"  # 字符串拼接
url = f"{domain}/blog"  # f-string
## 使用v()函数以后
v({
    "domain": "https://dongfanger.github.io"
})
url = v("${domain}/blog")

JSON字符串

## dict不兼容,注意看True和None
test_json = {
  "bool": True,
  "x": None,
  "customerId": "123456",
  "items": [
    {
      "productId": "987654",
      "quantity": 2,
      "price": 199.99
    }
  ],
  "shippingAddress": {
    "recipientName": "张三",
    "streetAddress": "北京市朝阳区某街道123号",
    "city": "北京",
    "state": "北京",
    "postalCode": "100000",
    "country": "中国"
  },
  "paymentMethod": {
    "type": "CreditCard",
    "cardNumber": "4111111111111111",
    "expiryDate": "12/25",
    "cvv": "123"
  },
  "orderNotes": "请尽快发货,谢谢!"
}
## 需要表达式
test_json["items"]["quantity"] = 3
test_json["orderNotes"] = "测试开发Gang"

Python的dict并不兼容JSON,需要把true改为True,null改为None,替换节点值也需要表达式。

使用函数v()以后:

v({
    "quantity": 3
    "orderNotes": "测试开发Gang"
})
template = """
{
  "bool": true,
  "x": null,
  "customerId": "123456",
  "items": [
    {
      "productId": "987654",
      "quantity": ${quantity},
      "price": 199.99
    }
  ],
  "shippingAddress": {
    "recipientName": "张三",
    "streetAddress": "北京市朝阳区某街道123号",
    "city": "北京",
    "state": "北京",
    "postalCode": "100000",
    "country": "中国"
  },
  "paymentMethod": {
    "type": "CreditCard",
    "cardNumber": "4111111111111111",
    "expiryDate": "12/25",
    "cvv": "123"
  },
  "orderNotes": "${orderNotes}"
}
"""
test_json = v(template)

变量池,字符串,占位符。

这就是tep3的函数v()。

用法介绍

1、初始化变量池,传入dict,v({"a": 1, "b": 2})

2、set变量,传入key和value,v("c", 3)

3、get变量,传入key,v("a")

4、替换字符串,传入占位符字符串,v("My name is ${gang}, hello")

需要注意的是,JSON是写成多行字符串,函数v()的输出是字符串类型,在post请求时,request("post", json=json.loads(v(body),v(body)是字符串,需要json.loads()转换为dict类型。

tep.request也对这个地方做了校验:

def _check(method, url, **kwargs) -> bool:
    json_param = kwargs["json"]
    if isinstance(json_param, str):
        logging.error("request() json expect dict type, json.loads() convert str to dict")
        return False

    return True

内置函数

函数v()不仅支持普通变量占位符,也支持函数占位符。

test_json = """
    "a": ${random()},  # 随机数
    "b": ${random(9)},  # 随机数,指定位数
    "c": "${random(前缀,2)}",  # 随机数,前缀和位数
    "d": "${uuid()}"  # uuid
    "e": "${time()}"  # 当前日期
    "f": "${time(%Y-%m-%d %H:%M:%S)}"  # 当前日期,指定日期格式
    "g": "${timestamp()}"  # 当前时间的时间戳
    "h": "${timestamp(2023-03-23 23:23:23)}"  # 指定时间的时间戳
"""

更多内置函数还在开发。欢迎加入交流群讨论添加哪些内置函数。

自定义函数也很简单,先编写个函数,把函数调用写入变量池:

v("name", self_defined_function())

再通过${name}引用。

tep版本

函数v()最新特性,请使用tep版本:

pip install tep==3.0.1

tep3函数v(),支持${}占位符语法,便捷管理接口数据。