18. 结合Selenium和YAML对页面继承对象PO的改造
18. 结合Selenium和YAML对页面继承对象PO的改造
一、架构改造核心思路
1.1 改造前后对比
1.2 核心优势
- 定位信息与代码解耦
- 支持多环境配置切换
- 提升代码可维护性
- 实现元素配置热更新
二、PO核心类改造解析
2.1 页面基类增强
class Page:elements_yml = {} # 子类需覆盖的配置映射elements_pool = {} # 配置缓存池def _locator(self, expression: str = 'cp.username'):key, value = expression.split('.')# 动态加载YAML配置if key not in self.elements_pool:self.elements_pool[key] = YamlReader(self.elements_yml[key]).data# 海象运算符验证定位方法if (locator := self.elements_pool[key][value])[0] not in BY_RULES:raise Exception(f'无效定位方法: {locator}')return self.elements_pool[key][value]
关键技术点:
- 双缓存机制(
elements_yml
与elements_pool
) - 表达式解析(
key.value
格式) - 定位方法白名单验证(
BY_RULES
)
三、配置管理系统升级
3.1 setting.py核心配置
# 元素配置文件映射
YAML_ELEMENT = {'cp': join(ELEMENTS_YAML_FILE_PATH, 'CommonLoginPass.yml'),'op': join(ELEMENTS_YAML_FILE_PATH, 'oder_page.yml')
}# 合法定位方法白名单
BY_RULES = ('id', 'xpath', 'link text', 'partial link text', 'name','tag name', 'class name', 'css selector'
)
3.2 路径管理优化
# 动态路径构建
ELEMENTS_YAML_FILE_PATH = join(BASE_PATH, 'Chap5\\page')
CHAPTER_1_PATH = join(BASE_PATH, 'chap3') # 跨平台兼容
四、页面类实现示例
4.1 登录页面改造
class CommonLoginPass(Page):elements_yml = YAML_ELEMENT # 绑定配置文件def login(self, username: str = 'Tester'):self.element('cp.username').send_keys(username) # 表达式驱动self.element('cp.password').send_keys(password)self.element('cp.loginBtn').click()
4.2 订单页面继承
class Oder(CommonLoginPass):def search_bug(self):self.element('op.clickOrder').click() # 继承配置映射self.element('op.orderInput').send_keys('Tom')
五、YAML配置文件规范
5.1 元素定义标准格式
# CommonLoginPass.yml
username:- id # 定位类型- ctl00_MainContent_username # 定位表达式loginBtn:- id- ctl00_MainContent_login_button
5.2 配置文件结构要求
- 二级键值为列表类型
- 首个元素必须为BY_RULES允许的定位方法
- 元素命名采用小驼峰格式
- 注释说明元素用途
六、执行流程优化
6.1 元素加载流程
6.2 性能优化策略
- 首次访问时加载配置文件
- 内存缓存已解析配置
- 避免重复IO操作
- 按需加载不同模块配置
七、改造收益分析
指标 | 改造前 | 改造后 | 提升率 |
---|---|---|---|
维护成本 | 需修改源代码 | 仅改配置文件 | 70% |
定位信息复用 | 类级别复用 | 跨项目复用 | 200% |
执行效率 | 每次重新定位 | 缓存加速访问 | 40% |
可读性 | 代码混杂定位 | 业务逻辑聚焦 | 60% |
八、完整代码
"""
Python :3.13.3
Selenium: 4.31.0po.py
"""from chap3.ob import *
from setting import *
from chap5.file_reader import YamlReaderclass Page:url = Nonedriver = None# 子类重写,获取通用配置文件中具体项目的元素配置文件字典elements_yml = {}# 缓存动态读取的yaml元素配置文件的解析结果elements_pool = {}def _locator(self, expression: str = 'cp.username'):"""解析元素表达式的方法:param expression::return:"""key, value = expression.split('.')if key not in self.elements_yml:raise Exception('元素配置文件的别名:{}无法识别!'.format(key))if key not in self.elements_pool:self.elements_pool[key] = YamlReader(self.elements_yml[key]).dataif (locator := self.elements_pool[key][value])[0] not in BY_RULES:raise Exception(f'无法识别定位方法:{locator}')return locatorreturn self.elements_pool[key][value]@classmethoddef cls_locator(cls, expression: str = 'cp.username'):"""类方法版本的locator,解析元素表达式:param expression: 元素表达式,格式为'配置文件别名.元素名':return: 定位元组(定位方式, 定位表达式)"""key, value = expression.split('.')if key not in cls.elements_yml:raise Exception('元素配置文件的别名:{}无法识别!'.format(key))if key not in cls.elements_pool:cls.elements_pool[key] = YamlReader(cls.elements_yml[key]).dataif (locator := cls.elements_pool[key][value])[0] not in BY_RULES:raise Exception(f'无法识别定位方法:{locator}')return locatorreturn cls.elements_pool[key][value]@classmethoddef cls_element(cls, loc: str):return cls.driver.find_element(*cls.cls_locator(loc))def element(self, loc: str):"""定位元素的方法:param loc::return:"""return self.driver.find_element(*self._locator(loc))def elements(self, loc: str):"""定位一组元素或多个元素:param loc::return:"""return self.driver.find_element(*self._locator(loc))class CommonLoginPass(Page):url = PROJECT_Oder_URLdriver = CHROME().start_chrome_browser# username = ('id', 'ctl00_MainContent_username')# password = ('id', 'ctl00_MainContent_password')# loginBtn = ('id', 'ctl00_MainContent_login_button')elements_yml = YAML_ELEMENTdef get(self):"""打开首页地址:return:"""self.driver.get(self.url)@classmethoddef cls_get(cls):"""类方法,打开首页:return:"""cls.driver.get(cls.url)def login(self, username: str = 'Tester', password: str = 'test'):# self.element(self.username).send_keys(username)# self.element(self.password).send_keys(password)# self.element(self.loginBtn).click()self.element('cp.username').send_keys(username)self.element('cp.password').send_keys(password)self.element('cp.loginBtn').click()@classmethoddef cls_login(cls, username: str = 'Tester', password: str = 'test'):"""类方法,登录:return:"""cls.cls_element('cp.username').send_keys(username)cls.cls_element('cp.password').send_keys(password)cls.cls_element('cp.loginBtn').click()class Oder(CommonLoginPass):# clickOrder = ('xpath', '//*[@id="ctl00_menu"]/li[3]/a')# orderInput = ('id', 'ctl00_MainContent_fmwOrder_txtName')# clickProcess = ('id', 'ctl00_MainContent_fmwOrder_InsertButton')## bug_label = ('id', "ctl00_MainContent_fmwOrder_RequiredFieldValidator3")# order_label = ('xpath', '//*[@id="aspnetForm"]//td[1]/h1')## invalid_login = ('xpath', '//*[@id="ctl00_MainContent_status"]')## log_out = ('xpath', '//*[@id="ctl00_logout"]')def search_bug(self, order_input: str = 'Tom'):self.element('op.clickOrder').click()self.element('op.orderInput').send_keys(order_input)self.element('op.clickProcess').click()def logout(self):self.element('op.log_out').click()class TestOder(Oder):"""测试登录和检索bug功能"""def test_login(self):self.get()self.login()assert self.element('op.order_label').text == 'Web Orders'print('test_login is passed')def test_search(self):self.search_bug()from time import sleepsleep(4)assert self.element('op.bug_label').text == "Field 'Street' cannot be empty."print('test_search is passed')self.driver.quit()obj = TestOder()
obj.test_login()
obj.test_search()
下面是setting.py的代码:
"""
Python :3.13.3
Selenium: 4.31.0
"""# 项目地址
# 项目包和文件夹的路径
# 浏览器对象属性
# 测试套件from os.path import dirname, join# -------------------项目地址-----------------------
# 项目一的地址
PROJECT_Oder_URL = 'http://secure.smartbearsoftware.com/samples/testcomplete12/WebOrders/Login.aspx'# 项目二的地址
PROJECT_QQ_URL = ''# 项目三的地址
PROJECT_DEMO_URL = ''# -------------------项目包和文件夹的路径-----------------------
# 项目根目录
BASE_PATH = dirname(__file__)# 浏览器驱动文件地址
CHROME_DRIVER_PATH = join(BASE_PATH, 'drivers\\chrome_driver.exe')
EDGE_DRIVER_PATH = join(BASE_PATH, 'driver\\edge_driver.exe')# 项目模块路径
# 模块1路径
CHAPTER_1_PATH = join(BASE_PATH, 'chap3')
# 模块2路径
CHAPTER_2_PATH = join(BASE_PATH, 'chap4')
# 模块3路径
CHAPTER_3_PATH = join(BASE_PATH, 'chap5')# 元素配置文件的根目录
ELEMENTS_YAML_FILE_PATH = join(BASE_PATH, 'Chap5\\page')
# -------------------测试套件-----------------------
# 流程1相关测试套件
SUIT_MODULE_1 = ['test_module_1.py','test_module_2.py'
]# 流程2相关测试套件
SUIT_MODULE_2 = ['test_module_1.py','test_module_2.py','test_module_3.py'
]# 流程3相关测试套件
SUIT_MODULE_3 = ['test_module_4.py','test_module_5.py'
]# 项目一的主测试套件
SUIT_PROJECT1 = ['test_module_1.py','test_module_2.py','test_module_3.py']# 项目二的主测试套件
SUIT_PROJECT2 = SUIT_MODULE_2 + SUIT_MODULE_3# -------------------浏览器对象属性-----------------------
# 浏览器基本属性# 无头化
HEADLESS = False# 隐式等待时间
IMP_TIME = 30# 页面加载超时时间
PAGE_LOAD_TIME = 20# JS异步执行超时时间
SCRIPT_TIME_OUT = 20# 浏览器尺寸
WINDOWS_SIZE = (1024, 768)# -------------------CHROME浏览器属性-----------------------# chrome浏览器操作开关
CHROME_METHOD_MARK = True# chrome启动参数开关
CHROME_OPTION_MARK = True# chrome实验性质启动参数
CHROME_EXP = {'excludeSwitches': ['enable-automation'],# 'mobileEmulation': {'deviceName': 'iPhone 6'}}# chrome窗口大小启动参数
CHROME_WINDOWS_SIZE = (1920, 900)# chrome启动最大化参数
CHROME_START_MAX = '--start-maximized'# -------------------EDGE浏览器属性-----------------------
# -------------------FIREFOX浏览器属性-----------------------# -------------------YAML元素配置文件-----------------------
YAML_ELEMENT = {'cp': join(ELEMENTS_YAML_FILE_PATH, 'CommonLoginPass.yml'),'op': join(ELEMENTS_YAML_FILE_PATH, 'oder_page.yml')
}
# -------------------YAML元素配置文件-----------------------#-------------------WEB元素定位方法-----------------------
BY_RULES = ('id','xpath','link text','partial link text','name','tag name','class name','css selector')
#-------------------WEB元素定位方法-----------------------
两份存放元素的yaml文件:
# 登录账号
username:- id- ctl00_MainContent_username# 密码
password:- id- ctl00_MainContent_password# 登录按钮
loginBtn:- id- ctl00_MainContent_login_button
# 点击‘Oder’按钮
clickOrder:- xpath- //*[@id="ctl00_menu"]/li[3]/a# 在字段‘Customer name’输入'Tom'
orderInput:- id- ctl00_MainContent_fmwOrder_txtName# 点击'Process'按钮
clickProcess:- id- ctl00_MainContent_fmwOrder_InsertButton# 检查‘Field 'Customer name' cannot be empty.’提示是否存在
bug_label:- id- ctl00_MainContent_fmwOrder_RequiredFieldValidator3# 检查‘Web Orders’标题是否存在
order_label:- xpath- //*[@id="aspnetForm"]//td[1]/h1# 检查账号密码错误时的提示内容
invalid_login:- xpath- //*[@id="ctl00_MainContent_status"]# 点击'logout'按钮
log_out:- xpath- //*[@id="ctl00_logout"]
「小贴士」:点击头像→【关注】按钮,获取更多软件测试的晋升认知不迷路! 🚀
相关文章:
18. 结合Selenium和YAML对页面继承对象PO的改造
18. 结合Selenium和YAML对页面继承对象PO的改造 一、架构改造核心思路 1.1 改造前后对比 #mermaid-svg-ziagMhNLS5fIFWrx {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-ziagMhNLS5fIFWrx .error-icon{fill:#5522…...
Vue-监听属性
监听属性 简单监听 点击切换名字,来回变更Tom/Jerry,输出 你好,Tom/Jerry 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><title>监听属性</title><!-- …...
AI写PPT可以用吗?我测试了3款AI写PPT工具,分享感受
上周五临下班,领导突然让我周末赶出一份季度营销报告 PPT,还要求周一晨会展示。看着空荡荡的 PPT 页面,我满心都是绝望 —— 周末不仅泡汤,搞不好还得熬夜到凌晨。好在同部门的前辈给我推荐了几款 AI 写 PPT 工具,没想…...
FreeSWITCH 简单图形化界面43 - 使用百度的unimrcp搞个智能话务台,用的在线的ASR和TTS
FreeSWITCH 简单图形化界面43 - 使用百度的unimrcp搞个智能话务台 0、一个fs的web配置界面预览1、安装unimrcp模块2、安装完成后,配置FreeSWITCH。2.1 有界面的配置2.1.1 mod_unimrcp模块配置2.1.2 mod_unimrcp客户端配置 2.2 无界面的配置 3、呼叫规则4、编写流程4…...
C 语言学习笔记(函数)
内容提要 函数 函数的概述函数的分类函数的定义形参和实参函数的返回值 函数 函数的概述 **函数:**实现一定功能的,独立的代码模块,对于函数的使用,一定是先定义,后使用。 使用函数的优势: ①我们可以…...
数据结构 -- 树形查找(二)平衡二叉树
平衡二叉树 定义 平衡二叉树(AVL树) – 树上的任意一点的左子树和右子树的高度之差不超过1 节点的平衡因子 左子树高-右子树高 平衡二叉树的结点的平衡因子的值只可能是-1、0、1 //平衡二叉树结点 typedef struct AVLNode{int key; //数据域int bal…...
day 29
类装饰器 类有修饰器,他的逻辑:接收一个类,返回一个修改后的类。例如 1. 添加新的方法或属性(如示例中的 log 方法)。 2. 修改原有方法(如替换 __init__ 方法,添加日志)。 3. 甚…...
Java 并发编程
黑马程序员深入学习Java并发编程 进程与线程 预备知识 java8,pom.xml <dependencies><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.10</version></depe…...
windows笔记本连接RKNN3588网络配置解析
这几天拿到了一块RKNN3588的板子,准备做视觉和Ros开发用,但是拿到后就蒙蔽了,不知道怎么ssh连到板子上去,更甚者不知道怎么配置网络让RKNN能够联网更新环境,这里记录一下整个过程。主要包括以下两个内容: 1.adb连接RKNN3588开发 2. 网口连接RKNN更新板子环境开发 adb连…...
C++ asio网络编程(8)处理粘包问题
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 粘包问题一、粘包原因总结: 二、如何处理粘包处理方法 三、完善消息节点MsgNode代码部分细节详解memcpy(_data, &max_len, HEAD_LENGTH);_data…...
【架构美学】Java 访问者模式:解构数据与操作的双重分发哲学
一、模式定义与核心思想 访问者模式(Visitor Pattern)是一种行为型设计模式,其核心目标是将数据操作与数据结构分离。通过定义一个独立的访问者类,使得新增对数据结构中元素的操作时,无需修改元素本身的类结构&#x…...
UE5无法编译问题解决
1. vs编译 2. 删除三个文件夹 参考...
Java可变参数与Collections工具类详解
Java可变参数与Collections工具类详解 一、可变参数(Variable Arguments) 1.1 基本概念 可变参数是Java 5引入的特性,允许在方法中定义数量可变的形参。其核心特点是:形参个数可以动态变化(0个、1个、多个ÿ…...
Git版本管理命令reset
目录 命令 git reset 场景一只回退 工作区代码 场景二回退暂存库与工作区 场景三回退暂存库,工作区,版本库内容 命令 git reset git reset --[soft/mixed(默认)/hard] [文件] soft:只回退版本库中内容 mixed:回退暂存区&…...
改进模糊C均值时序聚类+编码器状态识别!IPOA-FCM-Transformer组合模型
改进模糊C均值时序聚类编码器状态识别!IPOA-FCM-Transformer组合模型 目录 改进模糊C均值时序聚类编码器状态识别!IPOA-FCM-Transformer组合模型效果分析基本描述程序设计参考资料 效果分析 基本描述 1.创新未发表!研究亮点!时序…...
Zookeeper入门(三)
Zookeeper Java 客户端 项目构建 ookeeper 官方的客户端没有和服务端代码分离,他们为同一个jar 文件,所以我们直接引入 zookeeper的maven即可, 这里版本请保持与服务端版本一致,不然会有很多兼容性的问题 1 <dependency>…...
使用Redission来实现布隆过滤器
简述布隆过滤器 布隆过滤器是一种概率型数据结构,它可以用来判断一个元素是否在一个集合中。我们当时使用的是Redisson实现的布隆过滤器。它的底层原理是,先初始化一个比较大的数组,里面存放的是二进制0或1。一开始都是0,当一个k…...
Seata源码—6.Seata AT模式的数据源代理一
大纲 1.Seata的Resource资源接口源码 2.Seata数据源连接池代理的实现源码 3.Client向Server发起注册RM的源码 4.Client向Server注册RM时的交互源码 5.数据源连接代理与SQL句柄代理的初始化源码 6.Seata基于SQL句柄代理执行SQL的源码 7.执行SQL语句前取消自动提交事务的源…...
Spring-Beans的生命周期的介绍
目录 1、Spring核心组件 2、Bean组件 2.1、Bean的定义 2.2、Bean的生命周期 1、实例化 2、属性填充 3、初始化 4、销毁 2.3、Bean的执行时间 2.4、Bean的作用域 3、常见问题解决方案 4、与Java对象区别 前言 关于bean的生命周期,如下所示: …...
目标检测新突破:用MSBlock打造更强YOLOv8
文章目录 YOLOv8的现状与挑战YOLO-MS的MSBlock简介MSBlock的工作原理MSBlock的优势 利用MSBlock改进YOLOv8替换YOLOv8主干网络中的部分模块代码实现:替换CSP模块为MSBlock 在YOLOv8的颈部(Neck)中插入MSBlock代码实现:在颈部区域插…...
[SpringBoot]Spring MVC(4.0)
获取Header 传统获取 header 从 HttpServletRequest 中获取 RequestMapping("/r8")public String r8(HttpServletRequest request) {String userAgent request.getHeader("User-Agent");return "userAgent: "userAgent;}使用浏览器访问后&…...
Linux概述:从内核到开源生态
Linux概述:从内核到开源生态 Linux 是当今计算机领域最核心的开源操作系统内核,其影响力已渗透到服务器、嵌入式设备、云计算甚至超级计算机等各个领域。本章将深入解析Linux的本质、核心架构及其背后的开源哲学。 1. Linux的本质:不只是“操…...
【ubuntu24.04】pycharm 死机结束进程
windows 远程pycharm到ubuntu执行程序 pycharm 在调试过程中,内存耗尽,然后死机了 pycharm 进程 (base) rootk8s-master-pfsrv:/home/zhangbin/下载# ps -ef | grep pycharm root 121245 3230568 0 5月14 pts/8 00:00:00 /bin/bash --rcfile …...
【PRB】深度解析GaN中最浅的受主缺陷
2025 年 1 月 16 日,Virginia Commonwealth University 的 M. A. Reshchikov 和 SUNY–Albany 的 B. McEwen 等人在《Physical Review B》期刊发表了题为《Identity of the shallowest acceptor in GaN》的文章,基于对 50 多个 Be 掺杂 GaN 样品的光致发光实验以及 Heyd-Scus…...
Flink CEP是什么?
Apache Flink 的 CEP(Complex Event Processing,复杂事件处理) 是 Flink 提供的一个库,用于在无界数据流中检测符合特定模式的事件组合。 🎯 一、什么是 CEP? ✅ 定义: CEP 是一种从连续的数据…...
基于STM32的多传感器融合的设施农业小型搬运机器人避障控制系统设计
一、系统总体设计目标 针对设施农业场景中狭窄通道、障碍物多样(如农机具、作物植株、水管)的特点,设计一款基于 STM32 的小型搬运机器人避障控制系统。系统通过多传感器融合实现 360 环境感知,采用模糊 PID 控制算法实现平滑避障,满足温室、大棚等场景的搬运需求。 二、…...
从零开始实现大语言模型(十六):加载开源大语言模型参数
1. 前言 预训练大语言模型的难点不在于算法,而在于数据和算力,绝大多数企业和机构都没有预训练大语言模型的算力资源。在工业界的大语言模型应用实践中,通常会使用领域数据微调开源大语言模型参数,以构建领域大语言模型。 本文介…...
Spark,数据提取和保存
以下是使用 Spark 进行数据提取(读取)和保存(写入)的常见场景及代码示例(基于 Scala/Java/Python,不含图片操作): 一、数据提取(读取) 1. 读取文件数据&a…...
java19
1.集合体系结构 注意: 2.collection遍历之迭代器遍历 一次循环只能一次next方法的原因: 原因:集合长度是单数就报错 3.collection遍历之增强for遍历 如何代码简写呢:集合名.for回车 4.collection遍历之Lambda表达式遍历 5.使用多态…...
从0到1吃透卷积神经网络(CNN):原理与实战全解析
一、开篇:CNN 在 AI 领域的地位 在当今人工智能(AI)飞速发展的时代,卷积神经网络(Convolutional Neural Network,简称 CNN)无疑是深度学习领域中最为耀眼的明星之一 。它就像是 AI 世界里的超级…...
建一个结合双向长短期记忆网络(BiLSTM)和条件随机场(CRF)的模型
构建一个结合双向长短期记忆网络(BiLSTM)和条件随机场(CRF)的模型,通常用于序列标注任务,如命名实体识别(NER)、词性标注(POS Tagging)等。下面我将通过口述的…...
mvc-ioc实现
IOC 1)耦合/依赖 依赖,是谁离不开谁 就比如上诉的Controller层必须依赖于Service层,Service层依赖于Dao 在软件系统中,层与层之间存在依赖。我们称之为耦合 我们系统架构或者设计的一个原则是ÿ…...
符合Python风格的对象(再谈向量类)
再谈向量类 为了说明用于生成对象表示形式的众多方法,我们将使用一个 Vector2d 类,它与第 1 章中的类似。这一节和接下来的几节会不断实 现这个类。我们期望 Vector2d 实例具有的基本行为如示例 9-1 所示。 示例 9-1 Vector2d 实例有多种表示形式 &g…...
4.1.8文件共享
知识总览 基于索引节点的共享方式(硬链接): 让不同用户的文件目录项指向同一个文件的索引节点 用户1创建文件1,并让文件目录项aaa指向了文件1,这个文件对应了一个索引节点,这个索引节点 包含了文件的物理地址和文件的其他属性信…...
[LevelDB]LevelDB版本管理的黑魔法-为什么能在不锁表的情况下管理数据?
文章摘要 LevelDB的日志管理系统是怎么通过双链表来进行数据管理为什么LevelDB能够在不锁表的情况下进行日志新增 适用人群: 对版本管理机制有开发诉求,并且希望参考LevelDB的版本开发机制。数据库相关从业者的专业人士。计算机狂热爱好者,对计算机的…...
普通用户的服务器连接与模型部署相关记录
普通用户的服务器连接与模型部署相关记录 一、从登录到使用自己的conda 1.账号登陆: ssh xxx172.31.226.236 2.下载与安装conda: 下载conda: wget -c https://repo.anaconda.com/archive/Anaconda3-2023.03-1-Linux-x86_64.sh 安装con…...
WebSocket解决方案的一些细节阐述
今天我们来看看WebSocket解决方案的一些细节问题: 实际上,集成WebSocket的方法都有相关的工程挑战,这可能会影响项目成本和交付期限。在最简单的层面上,构建 WebSocket 解决方案似乎是添加接收实时更新功能的前进方向。但是&…...
架构思维:构建高并发扣减服务_分布式无主架构
文章目录 Pre无主架构的任务简单实现分布式无主架构 设计和实现扣减中的返还什么是扣减的返还返还实现原则原则一:扣减完成才能返还原则二:一次扣减可以多次返还原则三:返还的总数量要小于等于原始扣减的数量原则四:返还要保证幂等…...
C++函数基础:定义与调用函数,参数传递(值传递、引用传递)详解
1. 引言 函数是C编程中的核心概念之一,它允许我们将代码模块化,提高代码的可读性、复用性和可维护性。本文将深入探讨: 函数的定义与调用参数传递方式(值传递 vs 引用传递)应用场景与最佳实践 2. 函数的定义与调用 …...
深入解析Python中的Vector2d类:从基础实现到特殊方法的应用
引言 在Python面向对象编程中,特殊方法(或称魔术方法)是实现对象丰富行为的关键。本文将以Vector2d类为例,详细讲解如何通过特殊方法为自定义类添加多种表示形式和操作能力。 Vector2d类的基本行为 Vector2d类是一个二维向量类…...
【25软考网工】第六章(7)网络安全防护系统
博客主页:christine-rr-CSDN博客 专栏主页:软考中级网络工程师笔记 大家好,我是christine-rr !目前《软考中级网络工程师》专栏已经更新三十多篇文章了,每篇笔记都包含详细的知识点,希望能帮助到你&#x…...
Mac下载bilibili视频
安装 安装 yt-dlp brew install yt-dlp安装FFmpeg 用于合并音视频流、转码等操作 brew install ffmpeg使用 下载单个视频 查看可用格式 yt-dlp -F --cookies-from-browser chrome "https://www.bilibili.com/video/BV15B4y1G7F3?spm_id_from333.788.recommend_more_vid…...
6个月Python学习计划:从入门到AI实战(前端开发者进阶指南)
作者:一名前端开发者的进阶日志 计划时长:6个月 每日学习时间:2小时 覆盖方向:Python基础、爬虫开发、数据分析、后端开发、人工智能、深度学习 📌 目录 学习目标总览每日时间分配建议第1月:Python基础与编…...
批量处理 Office 文档 高画质提取图片、视频、音频素材助手
各位办公小能手们!你们有没有遇到过想从 Office 文档里提取图片、音频和视频,却又搞得焦头烂额的情况?今天就给大家介绍一款超厉害的工具——OfficeImagesExtractor! 这货的核心功能那可真是杠杠的!首先是高画质提取&a…...
【甲方安全建设】Python 项目静态扫描工具 Bandit 安装使用详细教程
文章目录 一、工具简介二、工具特点1.聚焦安全漏洞检测2.灵活的扫描配置3.多场景适配4.轻量且社区活跃三、安装步骤四、使用方法场景1:扫描单个Python文件场景2:递归扫描整个项目目录五、结果解读六、总结一、工具简介 Bandit 是由Python官方推荐的静态代码分析工具(SAST)…...
【推荐】新准则下对照会计报表172个会计科目解释
序号 科目名称 对应的会计报表项目 序号 科目名称 对应的会计报表项目 一、资产类 二、负债类 1 1001 库存现金 货币资金 103 2001 短期借款 短期借款 2 1002 银行存款 货币资金 104 2101 交易性金融负债 易性金融负债 3 1012 其他货币资…...
IntelliJ IDEA设置编码集
在IntelliJ IDEA中设置Properties文件的编码格式,主要涉及以下步骤和注意事项: 1. 全局和项目编码设置 打开设置界面:File -> Settings -> Editor -> File Encodings。在Global Encoding和Project Encoding下拉菜单中均选择UT…...
类魔方 :多变组合,灵活复用
文章目录 一、类的基础1. 类的基本结构与语法1. 类的定义与实例化2. 成员变量(属性)3. 构造函数(Constructor)4. 成员方法 2. 访问修饰符1. 基本访问规则2. 子类对父类方法的重写3. 构造函数的访问修饰符4. 参数属性与继承总结 3.…...
支持多方式拼接图片的软件
软件介绍 本文介绍一款名为 PicMerger 的图片拼接软件。 拼接亮点 PicMerger 这款软件最大的亮点在于,它能够将不同分辨率的图片完美地拼接在一起。拼接时会自动以分辨率最小的图片为标准,操作十分方便。 拼接方式与设置 该软件支持横向和纵向的拼接…...
Qt音视频开发过程中一个疑难杂症的解决方法/ffmpeg中采集本地音频设备无法触发超时回调
一、前言 最近在做实时音视频通话的项目中,遇到一个神奇的问题,那就是用ffmpeg采集本地音频设备,当音频设备拔掉后,采集过程会卡死在av_read_frame函数中,尽管设置了超时时间,也设置了超时回调interrupt_c…...