当前位置: 首页 > news >正文

Python自动化测试用例:如何优雅的完成Json格式数据断言

目录

前言

直接使用

优化

封装

小结

进阶

总结

 资料获取方法


前言

记录Json断言在工作中的应用进阶。

直接使用

很早以前写过一篇博客,记录当时获取一个多级json中指定key的数据:

#! /usr/bin/python
# coding:utf-8 
""" 
@author:Bingo.he 
@file: get_target_value.py 
@time: 2017/12/22 
"""
def get_target_value(key, dic, tmp_list):""":param key: 目标key值:param dic: JSON数据:param tmp_list: 用于存储获取的数据:return: list"""if not isinstance(dic, dict) or not isinstance(tmp_list, list):  # 对传入数据进行格式校验return 'argv[1] not an dict or argv[-1] not an list 'if key in dic.keys():tmp_list.append(dic[key])  # 传入数据存在则存入tmp_listfor value in dic.values():  # 传入数据不符合则对其value值进行遍历if isinstance(value, dict):get_target_value(key, value, tmp_list)  # 传入数据的value值是字典,则直接调用自身elif isinstance(value, (list, tuple)):_get_value(key, value, tmp_list)  # 传入数据的value值是列表或者元组,则调用_get_valuereturn tmp_listdef _get_value(key, val, tmp_list):for val_ in val:if isinstance(val_, dict):  get_target_value(key, val_, tmp_list)  # 传入数据的value值是字典,则调用get_target_valueelif isinstance(val_, (list, tuple)):_get_value(key, val_, tmp_list)   # 传入数据的value值是列表或者元组,则调用自身

优化

后来在写用例生成过程中,发现重复的断言描述信息较多,大多数数据返回其实都是标准的json,所以将整个返回的json放到断言数据中:

continue_run_flag = Truedef assert_json(base, juge, contain=(), reg=()):# 返回值,不符合预期时会设置为Falseflag = Truefor key, value in base.items():# 不进行断言的数据不进一步处理if key not in juge:continueif key in COMMON_RE_CHECK:if not re.match(COMMON_RE_CHECK[key], base[key]):flag = Falselogger.error("字段[{}]使用通用的正则匹配,不符合预期:预期正则匹配【{}】== 【{}】".format(key, COMMON_RE_CHECK[key], juge[key]))else:logger.warning("字段【{}】使用通用字段的正则匹配, 符合预期".format(key))continueif key in contain:if str(value) not in juge[key]:flag = Falselogger.error("字段[{}]不符合预期:预期【{}】包含 【{}】".format(key, juge[key], value))continuelogger.info("字段[{}]符合预期:预期[{}] 包含 [{}]".format(key, juge[key], value))continueif key in reg:if not re.match(juge[key], value):flag = Falselogger.error("字段[{}]不符合预期:预期正则匹配【{}】== 【{}】".format(key, value, juge[key]))continuelogger.info("字段[{}]断言成功:预期[{}]== 实际[{}]".format(key, value, juge[key]))continueif isinstance(value, str) or isinstance(value, int):if juge[key] != value:logger.error("字段[{}]不符合预期:预期【{}】!= 实际【{}】".format(key, value, juge[key]))flag = Falsecontinueelif isinstance(value, dict):assert_json(value, juge[key], contain=contain, reg=reg)elif isinstance(value, list):for i, v in enumerate(value):if isinstance(value, str) or isinstance(value, int):if v != juge[key][i]:logger.error("字段[{}]不符合预期:预期【{}】!= 实际【{}】".format(key, value, juge[key]))else:logger.info("字段[{}]断言成功:预期[{}]== 实际[{}]".format(key, value, juge[key]))elif isinstance(value, dict):assert_json(value[i], juge[key][i], contain=contain, reg=reg)else:assert_json(value[i], juge[key][i], contain=contain, reg=reg)else:passlogger.info("字段[{}]符合预期: 预期[{}]== 实际[{}]".format(key, value, juge[key]))# 失败是否继续执行,默认为TRUEif not continue_run_flag:assert flagreturn flag

调用:

rsp = requests.get('http://localhost:8800/get', params={"name": "bingo", "age": 18}).json()
assert_json(rsp, {"args": {"name": "bingo"},"headers": {"Accept": "*/*","Accept-Encoding": "gzip, deflate","Cache-Control": "max-age=259200","Host": "httpbin.org","User-Agent": "python-requests/2.27.1","X-Amzn-Trace-Id": r"Root=\d-\w{8}-\w{24}"},"req_param": [{"name": "bingo","age": "18"}],"origin": r"","url": "http://httpbin.org/get?name=bingo"
},
contain=(), reg=("X-Amzn-Trace-Id", "origin",))

日志效果:

2022-05-05 14:25:49.967 | INFO     | __main__:assert_json:173 - 字段[name]符合预期: 预期[bingo]== 实际[bingo]
2022-05-05 14:25:49.968 | INFO     | __main__:assert_json:173 - 字段[args]符合预期: 预期[{'name': 'bingo'}]== 实际[{'name': 'bingo'}]
2022-05-05 14:25:49.968 | INFO     | __main__:assert_json:173 - 字段[Accept]符合预期: 预期[*/*]== 实际[*/*]
2022-05-05 14:25:49.968 | INFO     | __main__:assert_json:173 - 字段[Accept-Encoding]符合预期: 预期[gzip, deflate]== 实际[gzip, deflate]
2022-05-05 14:25:49.968 | INFO     | __main__:assert_json:173 - 字段[Cache-Control]符合预期: 预期[max-age=259200]== 实际[max-age=259200]
2022-05-05 14:25:49.968 | INFO     | __main__:assert_json:173 - 字段[Host]符合预期: 预期[httpbin.org]== 实际[httpbin.org]
2022-05-05 14:25:49.968 | INFO     | __main__:assert_json:173 - 字段[User-Agent]符合预期: 预期[python-requests/2.27.1]== 实际[python-requests/2.27.1]
2022-05-05 14:25:49.968 | INFO     | __main__:assert_json:149 - 字段[X-Amzn-Trace-Id]断言成功:预期[Root=1-62734553-430db0707e1a3656043cd165]== 实际[Root=\d-\w{8}-\w{24}]
2022-05-05 14:25:49.968 | INFO     | __main__:assert_json:173 - 字段[headers]符合预期: 预期[{'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Cache-Control': 'max-age=259200', 'Host': 'httpbin.org', 'User-Agent': 'python-requests/2.27.1', 'X-Amzn-Trace-Id': 'Root=1-62734553-430db0707e1a3656043cd165'}]== 实际[{'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Cache-Control': 'max-age=259200', 'Host': 'httpbin.org', 'User-Agent': 'python-requests/2.27.1', 'X-Amzn-Trace-Id': 'Root=\\d-\\w{8}-\\w{24}'}]
2022-05-05 14:25:49.969 | WARNING  | __main__:assert_json:133 - 字段【origin】使用通用字段的正则匹配, 符合预期
2022-05-05 14:25:49.969 | INFO     | __main__:assert_json:173 - 字段[age]符合预期: 预期[18]== 实际[18]
2022-05-05 14:25:49.969 | INFO     | __main__:assert_json:173 - 字段[name]符合预期: 预期[bingo]== 实际[bingo]
2022-05-05 14:25:49.969 | INFO     | __main__:assert_json:173 - 字段[req_param]符合预期: 预期[[{'age': '18', 'name': 'bingo'}]]== 实际[[{'name': 'bingo', 'age': '18'}]]
2022-05-05 14:25:49.969 | INFO     | __main__:assert_json:173 - 字段[url]符合预期: 预期[http://httpbin.org/get?name=bingo]== 实际[http://httpbin.org/get?name=bingo]

封装

将方法简单封装到调用类中:

class HttpBin:def __init__(self):self.continue_run_flag = True  # 失败是否继续执行self.base_url = 'http://localhost:8800'self.base_param = {"local_class": self.__class__.__name__}def get(self, param):path = "/get"param.update(self.base_param)self.rsp = requests.get(self.base_url + path, params=param)self.ans = self.rsp.json()logger.info(json.dumps(self.rsp.json(), indent=4))return selfdef set(self, param):path = "/set"param.update(self.base_param)self.rsp = requests.get(self.base_url + path, params=param)self.ans = self.rsp.json()logger.info(json.dumps(self.rsp.json(), indent=4))return selfdef assert_statusCode(self, result_code):""":param result_code: 包含关系断言:return: bool <= self.rsp.resultinfo"""# 返回值,不符合预期时会设置为Falseflag = Trueif int(result_code) != self.rsp.status_code:logger.error(f"返回状态码[result_code]不符合预期:预期【{result_code}】!= 实际【{self.rsp.status_code}】")flag = Falseelse:logger.info(f"返回状态码[result_code]符合预期:预期【{result_code}】!= 实际【{self.rsp.status_code}】")if not self.continue_run_flag:assert flagreturn selfdef assert_json_body(self, base, juge, contain=(), reg=()):...

用例调用

# 如果仅仅断言状态码
HttpBin().get({"name": "bingo", "age": 18}).assert_statusCode(200)# 级连调用多个接口,使用同一个初始化数据
HttpBin().get({"name": "bingo", "age": 18}).assert_statusCode(200).\set({"name": "he", "age": 18}).assert_statusCode(200).assert_json_body(juge={"args": {"name": "bingo"},"headers": {"Accept": "*/*","Accept-Encoding": "gzip, deflate","Cache-Control": "max-age=259200","Host": "httpbin.org","User-Agent": "python-requests/2.27.1","X-Amzn-Trace-Id": r"Root=\d-\w{8}-\w{24}"},"req_param": [{"name": "he","age": "18"}],"origin": r"","url": "http://httpbin.org/set?name=bingo"}, contain=(), reg=("X-Amzn-Trace-Id", "origin",))

运行效果:

2022-05-05 19:39:36.951 | INFO     | __main__:assert_statusCode:53 - 返回状态码[result_code]符合预期:预期【200】!= 实际【200】
2022-05-05 19:39:36.951 | INFO     | __main__:assert_json_body:117 - 字段[name]符合预期: 预期[bingo]== 实际[bingo]
2022-05-05 19:39:36.951 | INFO     | __main__:assert_json_body:117 - 字段[args]符合预期: 预期[{'name': 'bingo'}]== 实际[{'name': 'bingo'}]
2022-05-05 19:39:36.952 | INFO     | __main__:assert_json_body:117 - 字段[Accept]符合预期: 预期[*/*]== 实际[*/*]
2022-05-05 19:39:36.952 | INFO     | __main__:assert_json_body:117 - 字段[Accept-Encoding]符合预期: 预期[gzip, deflate]== 实际[gzip, deflate]
2022-05-05 19:39:36.952 | INFO     | __main__:assert_json_body:117 - 字段[Cache-Control]符合预期: 预期[max-age=259200]== 实际[max-age=259200]
2022-05-05 19:39:36.952 | INFO     | __main__:assert_json_body:117 - 字段[Host]符合预期: 预期[httpbin.org]== 实际[httpbin.org]
2022-05-05 19:39:36.952 | INFO     | __main__:assert_json_body:117 - 字段[User-Agent]符合预期: 预期[python-requests/2.27.1]== 实际[python-requests/2.27.1]
2022-05-05 19:39:36.952 | INFO     | __main__:assert_json_body:93 - 字段[X-Amzn-Trace-Id]断言成功:预期[Root=1-62734553-430db0707e1a3656043cd165]== 实际[Root=\d-\w{8}-\w{24}]
2022-05-05 19:39:36.952 | INFO     | __main__:assert_json_body:117 - 字段[headers]符合预期: 预期[{'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Cache-Control': 'max-age=259200', 'Host': 'httpbin.org', 'User-Agent': 'python-requests/2.27.1', 'X-Amzn-Trace-Id': 'Root=1-62734553-430db0707e1a3656043cd165'}]== 实际[{'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Cache-Control': 'max-age=259200', 'Host': 'httpbin.org', 'User-Agent': 'python-requests/2.27.1', 'X-Amzn-Trace-Id': 'Root=\\d-\\w{8}-\\w{24}'}]
2022-05-05 19:39:36.953 | WARNING  | __main__:assert_json_body:77 - 字段【origin】使用通用字段的正则匹配, 符合预期
2022-05-05 19:39:36.953 | INFO     | __main__:assert_json_body:117 - 字段[age]符合预期: 预期[18]== 实际[18]
2022-05-05 19:39:36.953 | INFO     | __main__:assert_json_body:117 - 字段[name]符合预期: 预期[he]== 实际[he]
2022-05-05 19:39:36.953 | INFO     | __main__:assert_json_body:117 - 字段[req_param]符合预期: 预期[[{'age': '18', 'local_class': 'HttpBin', 'name': 'he'}]]== 实际[[{'name': 'he', 'age': '18'}]]
2022-05-05 19:39:36.953 | INFO     | __main__:assert_json_body:117 - 字段[url]符合预期: 预期[http://httpbin.org/set?name=bingo]== 实际[http://httpbin.org/set?name=bingo]

小结

  • 可以作为独立函数使用,也可以和所有的接口一起封装,灵活度、复用度高
  • 用例极简且逻辑清晰
  • 支持断言失败,用例继续执行(开关控制),方便一次性发现所有的差异
  • 极易编写的统一断言(从日志获取轻松获取
    • 用例运行日志,断言数据字段清晰明确
    • 可统一化处理新版本修改字段,无需修改每个用例
    • 支持正则匹配
    • 支持**包含匹配 **
    • 支持错误码直接断言
  • 集中初始化原始常用数据,不同业务适配简单,重写初始化方法即可

进阶

上面的方法虽然使用日志的方法记录了所有的差异,但是面对大json对比的时候,很难直接标记出具体的差异位置。在做现网引流对比测试的时候就出现了这样的需求,从现网拉取的账户数据可能存在几百个子账户,每个子账户有20多个属性字段,怎么准确标记他们在新旧系统的写操作后不一致的情况成为了一个小卡点。

话不多说,思路:利用列表可变特性和生成器关键字yield特性递归分解json,生成一个固定的数组,最终比较数组中的数据

代码:

def recurse(d, prefix=None, sep='.'):if prefix is None:prefix = []for key, value in d.items():if isinstance(value, dict):yield from recurse(value, prefix + [key])elif isinstance(value, list):for i, v in enumerate(value):if isinstance(v, dict):yield from recurse(v, prefix + [key, f"${i}"])# 兼容 包含数字的类型elif isinstance(v, int) or isinstance(v, str):yield sep.join(prefix + [key, str(value)])  # 会嵌套上valueelse:# print(key)yield sep.join(prefix + [key, str(value)])  # 会嵌套上value

效果:

print(json.dumps(list(recurse({"args": {"name": "bingo"},"headers": {"Accept": "*/*","Accept-Encoding": "gzip, deflate","Cache-Control": "max-age=259200","Host": "httpbin.org","User-Agent": "python-requests/2.27.1","X-Amzn-Trace-Id": r"Root=\d-\w{8}-\w{24}"},"req_param": [{"name": "bingo","age": "18"},{"name": "he","age": "19"},{"name": "detector","age": "20"}],"origin": r"","url": "http://httpbin.org/set?name=bingo"})), indent=4))
# 输出
["args.name.bingo","headers.Accept.*/*","headers.Accept-Encoding.gzip, deflate","headers.Cache-Control.max-age=259200","headers.Host.httpbin.org","headers.User-Agent.python-requests/2.27.1","headers.X-Amzn-Trace-Id.Root=\\d-\\w{8}-\\w{24}","req_param.$0.name.bingo","req_param.$0.age.18","req_param.$1.name.he","req_param.$1.age.19","req_param.$2.name.detector","req_param.$2.age.20","origin.","url.http://httpbin.org/set?name=bingo"
]

总结

项目实践中总会遇到这样那样的需求,每个方法都有适用的场景,直接高效解决问题是第一要务。

  • json查找数据
  • json数据用例封装对比
  • json数据转化

 资料获取方法

【留言777】

各位想获取源码等教程资料的朋友请点赞 + 评论 + 收藏,三连!

三连之后我会在评论区挨个私信发给你们~

相关文章:

Python自动化测试用例:如何优雅的完成Json格式数据断言

目录 前言 直接使用 优化 封装 小结 进阶 总结 资料获取方法 前言 记录Json断言在工作中的应用进阶。 直接使用 很早以前写过一篇博客&#xff0c;记录当时获取一个多级json中指定key的数据&#xff1a; #! /usr/bin/python # coding:utf-8 """ aut…...

阿里云对象存储服务OSS

1、引依赖 <dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>3.15.1</version> </dependency> <dependency><groupId>javax.xml.bind</groupId><artifa…...

第三节:在WORD为应用主窗口下关闭EXCEL的操作(1)

【分享成果&#xff0c;随喜正能量】夏日里的遗憾&#xff0c;一定都会被秋风温柔化解。吃素不难&#xff0c;难于不肯捨贪口腹之心。若不贪口腹&#xff0c;有何吃素之不便乎。虽吃华素&#xff0c;不吃素日&#xff0c;亦须少吃。以一切物类&#xff0c;皆是贪生怕死&#xf…...

mybatis 缓存

很久没有弄mybatis了&#xff0c;以至于今天在使用时忘记了一个很重事情&#xff08;缓存&#xff09;&#xff0c;导致始终读取不数据库更新之后的最新的数据&#xff0c;后来折腾了小半天才想起缓存&#xff0c;所有小记住一下关闭mybatis的缓存 mybatis.configuration.cach…...

分布式Redis详解

目录 前言安装redis的俩种方法Redis 与 MySQL的区别Redis可以实现那些功能Redis常用的数据类型有序列表的底层是如何实现的?什么是跳跃表 Redis在Spring中的使用Redis 中为什么单线程比多线程快Redis的分布式锁如何实现Redis 分布式锁可能出现的问题Redis保持数据不丢失的方式…...

揭秘程序员和技师的7大共同点,最后一点绷不住了

大家好&#xff0c;这里是程序员晚枫&#xff0c;周末朋友出去放松回来&#xff0c;给我分析了一下程序员和技师的7个相同点&#xff0c;尤其是最后一点让我彻底绷不住了&#xff01; 我也分享给大家。 1、都有工号。98号技师&#xff0c;380号技师大家都很熟悉了&#xff0c…...

SQL | 使用函数处理数据

8-使用函数处理数据 8.1-函数 SQL可以用函数来处理数据。函数一般是在数据上执行的&#xff0c;为数据的转换和处理提供了方便。 8.1.1 函数带来的问题 每种DBMS都有特定的函数&#xff0c;只有很少一部分函数&#xff0c;是被所有主要的DBMS等同的支持。 虽然所有的类型的…...

基于Dlib库+SVM+Tensorflow+PyQT5智能面相分析-机器学习算法应用(含全部工程源码)+训练及测试数据集

目录 前言总体设计系统整体结构图系统流程图模型流程 运行环境Python 环境TensorFlow环境界面编程环境 模块实现1. 数据预处理2. 模型构建1&#xff09;定义模型结构2&#xff09;交叉验证模型优化 3. 模型训练及保存4. 模型测试1&#xff09;摄像头调用2&#xff09;模型导入及…...

【Flutter】【packages】simple_animations 简单的实现动画

package&#xff1a;simple_animations 导入包到项目中去 可以实现简单的动画&#xff0c; 快速实现&#xff0c;不需要自己过多的设置 有多种样式可以实现[ ] 功能&#xff1a; 简单的用例&#xff1a;具体需要详细可以去 pub 链接地址 1. PlayAnimationBuilder PlayAnima…...

python之matplotlib入门初体验:使用Matplotlib进行简单的图形绘制

目录 绘制简单的折线图1.1 修改标签文字和线条粗细1.2 校正图形1.3 使用内置样式1.4 使用scatter()绘制散点图并设置样式1.5 使用scatter()绘制一系列点1.6 python循环自动计算数据1.7 自定义颜色1.8 使用颜色映射1.9 自动保存图表练习题 绘制简单的折线图 绘制一个简单折线图…...

[Linux kernel] [ARM64] boot 流程梳理

一、启动汇编代码部分 0. 链接文件找代码段入口 – _text arch/arm64/kernel/vmlinux.lds.S ENTRY(_text). KIMAGE_VADDR;.head.text : {_text .;HEAD_TEXT}.text : ALIGN(SEGMENT_ALIGN) { /* Real text segment */_stext .; /* Text and read-only data */IRQENTRY_TE…...

重建二叉树

输入一棵二叉树前序遍历和中序遍历的结果&#xff0c;请重建该二叉树。 注意: 二叉树中每个节点的值都互不相同&#xff1b;输入的前序遍历和中序遍历一定合法&#xff1b; 数据范围 树中节点数量范围 [0,100] 。 样例 给定&#xff1a; 前序遍历是&#xff1a;[3, 9, 2…...

支付整体架构

5.4 支付的技术架构 架构即未来&#xff0c;只有建立在技术架构设计良好的体系上&#xff0c;支付机构才能有美好的未来。如果支付的技术体系在架构上存在问题&#xff0c;那么就没有办法实现高可用性、高安全性、高效率和水平可扩展性。 总结多年来在海内外支付机构主持和参与…...

百度智能云:千帆大模型平台接入Llama 2等33个大模型,上线103个Prompt模板

大家好&#xff0c;我是herosunly。985院校硕士毕业&#xff0c;现担任算法研究员一职&#xff0c;热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名&#xff0c;CCF比赛第二名&#xff0c;科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的…...

烦人的幻灯片——拓扑排序

烦人的幻灯片 烦人的幻灯片问题描述输入输出格式输入格式输出格式 输入输出样例输入样例&#xff1a;输入样例一&#xff1a;输入样例二&#xff1a; 输出样例&#xff1a;输出样例一&#xff1a;输出样例二&#xff1a; 正确做法拓扑排序 代码 烦人的幻灯片 问题描述 李教授…...

无涯教程-Perl - ord函数

描述 此函数返回EXPR指定的字符的ASCII数值,如果省略则返回$_。例如,ord(A)返回值为65。 语法 以下是此函数的简单语法- ord EXPRord返回值 该函数返回整数。 例 以下是显示其基本用法的示例代码- #!/usr/bin/perl -wprint("ord() ", ord(G), "\n"…...

Python爬虫:js逆向调式操作及调式中遇到debugger问题

Python爬虫:js逆向调式操作及调式中遇到debugger问题 1. 前言2. js逆向调式操作2.1 DOM事件断点2.2 XHR/提取断点(用于请求接口参数加密处理)2.3 请求返回的数据是加密的2.4 hook定位参数 3. 调式中遇到debugger问题3.1 解决方式(一律不在此处暂停)3.2 问题&#xff1a;点击一律…...

HTML网页制作技巧:打造出色的用户体验

HTML是构建网页的基础语言&#xff0c;掌握一些关键的技巧可以帮助您创建出色的用户体验。本文将介绍一些HTML网页制作的技巧&#xff0c;从布局和样式到交互和可访问性&#xff0c;为您提供有用的指导。无论您是初学者还是有经验的开发者&#xff0c;这些技巧都将对您的网页设…...

探究使用HTTP代理ip后无法访问网站的原因与解决方案

目录 访问网站的原理是什么 1. DNS解析 2. 建立TCP连接 3. 发送HTTP请求&#xff1a; 4. 服务器响应&#xff1a; 5. 浏览器渲染&#xff1a; 6. 页面展示&#xff1a; 使用代理IP后访问不了网站&#xff0c;有哪些方面的原因 1. 代理IP的可用性&#xff1a; 2. 代理…...

SpringBoot 全局异常处理进阶

待总结 参考文章&#xff1a; SpringBoot 全局异常处理进阶&#xff1a;使用 ControllerAdvice 对不同的 Controller 分别捕获异常并处理 SpringBoot 对 controller 层捕获全局异常并处理的方法&#xff08;ControllerAdvice 和 ExceptionHandler&#xff09; 注解RestCont…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销&#xff0c;平衡网络负载&#xff0c;延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中&#xff0c;我们渴望一个能激发创想、愉悦感官的工作与生活伙伴&#xff0c;它不仅是冰冷的科技工具&#xff0c;更能触动我们内心深处的细腻情感。正是在这样的期许下&#xff0c;华硕a豆14 Air香氛版翩然而至&#xff0c;它以一种前所未有的方式&#x…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)

前言&#xff1a; 在Java编程中&#xff0c;类的生命周期是指类从被加载到内存中开始&#xff0c;到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期&#xff0c;让读者对此有深刻印象。 目录 ​…...

多模态图像修复系统:基于深度学习的图片修复实现

多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...

C# 表达式和运算符(求值顺序)

求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如&#xff0c;已知表达式3*52&#xff0c;依照子表达式的求值顺序&#xff0c;有两种可能的结果&#xff0c;如图9-3所示。 如果乘法先执行&#xff0c;结果是17。如果5…...

c++第七天 继承与派生2

这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分&#xff1a;派生类构造函数与析构函数 当创建一个派生类对象时&#xff0c;基类成员是如何初始化的&#xff1f; 1.当派生类对象创建的时候&#xff0c;基类成员的初始化顺序 …...

实战三:开发网页端界面完成黑白视频转为彩色视频

​一、需求描述 设计一个简单的视频上色应用&#xff0c;用户可以通过网页界面上传黑白视频&#xff0c;系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观&#xff0c;不需要了解技术细节。 效果图 ​二、实现思路 总体思路&#xff1a; 用户通过Gradio界面上…...

保姆级【快数学会Android端“动画“】+ 实现补间动画和逐帧动画!!!

目录 补间动画 1.创建资源文件夹 2.设置文件夹类型 3.创建.xml文件 4.样式设计 5.动画设置 6.动画的实现 内容拓展 7.在原基础上继续添加.xml文件 8.xml代码编写 (1)rotate_anim (2)scale_anim (3)translate_anim 9.MainActivity.java代码汇总 10.效果展示 逐帧…...

【安全篇】金刚不坏之身:整合 Spring Security + JWT 实现无状态认证与授权

摘要 本文是《Spring Boot 实战派》系列的第四篇。我们将直面所有 Web 应用都无法回避的核心问题&#xff1a;安全。文章将详细阐述认证&#xff08;Authentication) 与授权&#xff08;Authorization的核心概念&#xff0c;对比传统 Session-Cookie 与现代 JWT&#xff08;JS…...

多元隐函数 偏导公式

我们来推导隐函数 z z ( x , y ) z z(x, y) zz(x,y) 的偏导公式&#xff0c;给定一个隐函数关系&#xff1a; F ( x , y , z ( x , y ) ) 0 F(x, y, z(x, y)) 0 F(x,y,z(x,y))0 &#x1f9e0; 目标&#xff1a; 求 ∂ z ∂ x \frac{\partial z}{\partial x} ∂x∂z​、 …...