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

Python+Requests+Pytest+YAML+Allure接口自动化框架

GitHub源码地址(详细注释):源码

调试项目python自主搭建:附项目源码

一、项目介绍

本项目是基于 Python+Requests+Pytest+YAML+Allure 搭建的 接口自动化测试框架,用于对 REST API 进行测试。
框架的主要特点包括:

  • 块化设计:采用 分层架构,包括 API 层、业务层、数据层、公共模块、测试用例层,增强可维护性。
  • Pytest 测试框架:使用 Pytest 进行测试组织、执行、夹具管理,并提供强大的插件支持。
  • Requests 进行 API 测试:封装 HTTP 请求,简化 API 调用流程。
  • YAML 管理测试数据:测试数据与代码解耦,支持多环境测试。
  • Allure 生成测试报告:提供清晰直观的测试报告,支持测试历史分析。

二、目录结构

PytestDemo/
│── api/                  # 接口封装层,封装用户相关的 API
│   ├── user.py 			# 提供底层 API 访问接口,与后端 API 进行交互
│── common/               # 公共模块(日志、数据库操作、HTTP 请求封装)
│   ├── logger.py         # 日志管理
│   ├── mysql_operate.py  # 数据库操作
│   ├── read_data.py      # 读取 YAML 文件数据
│── config/               # 配置文件(环境变量、测试数据)
│   ├── setting.ini       # MySQL 环境配置
│── core/                 # requests 请求方法封装、关键字返回结果类
│   ├── rest_client.py    # 简化 HTTP 请求的发送,并提供日志记录功能
│   ├── result_base.py    # 结果基类,用于定义接口返回结果的标准结构
│── data/                 # 测试数据文件管理
│   ├── api_test_data.yml 
│   ├── base_data.yml     
│   ├── scenario_test_data.yml     
│── log/                  # 日志文件
│   ├── 20250324.log     
│── operation/            # 业务层(对接口请求进行封装)
│   ├── user.py           # 业务api封装,供测试用例调用。
│── testcases/            # 测试用例
│   ├── report/           # Allure 测试报告
│   ├── api_test/         # 单接口 API 用例集
│   ├── scenario_test/    # 业务链 API 用例集
│── conftest.py           # Pytest 夹具(Fixture)
│── requirements.txt      # 依赖包清单
│── pytest.ini            # Pytest 配置文件

三、框架分层详解

1. api/:接口封装层

import os  # 导入os模块,用于文件和目录操作
from core.rest_client import RestClient  # 从core模块导入RestClient类
from common.read_data import data  # 从common模块导入data类,用于读取数据# 获取当前文件所在的目录的上一级目录路径
BASE_PATH = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
# 构造配置文件setting.ini的完整路径
data_file_path = os.path.join(BASE_PATH, "config", "setting.ini")
# 读取配置文件中的API根URL
api_root_url = data.load_ini(data_file_path)["host"]["api_root_url"]class User(RestClient):  # 继承RestClient类,封装用户相关的接口def __init__(self, api_root_url, **kwargs):"""初始化User类,调用父类的构造方法:param api_root_url: API的根URL:param kwargs: 其他可选参数"""super(User, self).__init__(api_root_url, **kwargs)def list_all_users(self, **kwargs):"""获取所有用户列表:param kwargs: 其他可选参数:return: GET请求返回的响应结果"""return self.get("/users", **kwargs)def list_one_user(self, username, **kwargs):"""获取指定用户名的用户信息:param username: 用户名:param kwargs: 其他可选参数:return: GET请求返回的响应结果"""return self.get("/users/{}".format(username), **kwargs)def register(self, **kwargs):"""用户注册:param kwargs: 包含注册所需参数:return: POST请求返回的响应结果"""return self.post("/register", **kwargs)def login(self, **kwargs):"""用户登录:param kwargs: 包含登录所需参数:return: POST请求返回的响应结果"""return self.post("/login", **kwargs)def update(self, user_id, **kwargs):"""更新用户信息:param user_id: 需要更新的用户ID:param kwargs: 包含更新内容:return: PUT请求返回的响应结果"""return self.put("/update/user/{}".format(user_id), **kwargs)def delete(self, name, **kwargs):"""删除用户:param name: 需要删除的用户名:param kwargs: 其他可选参数:return: POST请求返回的响应结果"""return self.post("/delete/user/{}".format(name), **kwargs)user = User(api_root_url)  # 创建User类的实例,并传入API根URL

作用:
这一层直接与后端 API 交互,实现最基础的接口请求
不处理业务逻辑,只负责请求和返回数据,调用时只需传入参数
继承 RestClient 统一管理 HTTP 请求

2. 公共模块 (common/)

2.1 日志管理 (common/logger.py)

import logging  # 导入logging模块,用于记录日志
import time  # 导入time模块,用于获取当前时间
import os  # 导入os模块,用于文件和目录操作# 获取当前文件所在的目录的上一级目录路径
BASE_PATH = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))# 定义日志文件存放的目录路径
LOG_PATH = os.path.join(BASE_PATH, "log")# 如果日志目录不存在,则创建日志目录
if not os.path.exists(LOG_PATH):os.mkdir(LOG_PATH)class Logger:"""Logger类用于配置和管理日志记录"""def __init__(self):"""初始化Logger类,创建日志记录器"""# 定义日志文件的完整路径,文件名为当前日期.logself.logname = os.path.join(LOG_PATH, "{}.log".format(time.strftime("%Y%m%d")))# 创建一个日志记录器实例,名称为"log"self.logger = logging.getLogger("log")# 设置日志记录器的级别为DEBUG,表示记录所有级别的日志self.logger.setLevel(logging.DEBUG)# 定义日志格式self.formater = logging.Formatter('[%(asctime)s][%(filename)s %(lineno)d][%(levelname)s]: %(message)s')# 创建一个日志文件处理器,用于将日志写入文件self.filelogger = logging.FileHandler(self.logname, mode='a', encoding="UTF-8")# 创建一个控制台处理器,用于在控制台输出日志self.console = logging.StreamHandler()# 设置控制台日志级别为DEBUGself.console.setLevel(logging.DEBUG)# 设置文件日志级别为DEBUGself.filelogger.setLevel(logging.DEBUG)# 为文件日志处理器和控制台日志处理器设置相同的日志格式self.filelogger.setFormatter(self.formater)# 设置控制台日志的格式self.console.setFormatter(self.formater)# 将文件日志处理器添加到日志记录器self.logger.addHandler(self.filelogger)# 将控制台日志处理器添加到日志记录器self.logger.addHandler(self.console)# 创建Logger类的实例,并获取日志记录器
logger = Logger().loggerif __name__ == '__main__':logger.info("---测试开始---")  # 记录INFO级别日志logger.debug("---测试结束---")  # 记录DEBUG级别日志

作用:
封装日志模块,记录测试执行过程。
使用方式:

from common.logger import loggerlogger.info("这是一条测试日志")

2.2 数据库操作(common/mysql_operate.py)

import pymysql  # 导入pymysql库,用于操作MySQL数据库
import os  # 导入os模块,用于路径操作
from common.read_data import data  # 从common模块中导入读取数据的方法
from common.logger import logger  # 从common模块中导入日志记录器# 获取当前文件的上级目录路径
BASE_PATH = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
# 定义配置文件的路径
data_file_path = os.path.join(BASE_PATH, "config", "setting.ini")
# 读取配置文件中的 MySQL 配置信息
data = data.load_ini(data_file_path)["mysql"]# 从配置文件中提取MySQL连接所需的参数,并存储在字典中
DB_CONF = {"host": data["MYSQL_HOST"],        # 数据库主机地址"port": int(data["MYSQL_PORT"]),   # 数据库端口号"user": data["MYSQL_USER"],        # 数据库用户名"password": data["MYSQL_PASSWD"],  # 数据库密码"db": data["MYSQL_DB"]             # 数据库名称
}class MysqlDb():"""MysqlDb 类用于封装 MySQL 数据库的连接和操作方法。"""def __init__(self, db_conf=DB_CONF):"""初始化MySQL连接:param db_conf: 数据库配置字典,包含连接MySQL所需的配置信息"""# 通过字典拆包传递数据库配置信息,建立数据库连接self.conn = pymysql.connect(**db_conf, autocommit=False)# 通过 cursor() 方法创建游标对象,并让查询结果以字典格式输出self.cur = self.conn.cursor(cursor=pymysql.cursors.DictCursor)def __del__(self):"""释放数据库资源,在对象被删除时自动调用"""# 关闭游标self.cur.close()# 关闭数据库连接self.conn.close()def select_db(self, sql):"""执行查询操作:param sql: 要执行的SQL查询语句:return: 查询结果(列表格式)"""# 检查数据库连接是否断开,如果连接断开则重新建立连接self.conn.ping(reconnect=True)# 执行SQL查询self.cur.execute(sql)# 获取查询结果data = self.cur.fetchall()return datadef execute_db(self, sql):"""执行更新、插入或删除操作:param sql: 要执行的SQL语句(更新/插入/删除)"""try:# 检查数据库连接是否断开,如果连接断开则重新建立连接self.conn.ping(reconnect=True)# 执行SQL语句self.cur.execute(sql)# 提交事务self.conn.commit()except Exception as e:# 捕获异常并记录错误日志logger.info("操作MySQL出现错误,错误原因:{}".format(e))# 如果发生异常,回滚事务self.conn.rollback()# 创建MysqlDb对象并使用DB_CONF进行初始化
db = MysqlDb(DB_CONF)

作用:
封装 MySQL 连接,支持数据查询、执行 SQL 语句。
使用方式:

db = MysqlDb()
data = db.select_db("SELECT * FROM user")

2.3 读取配置文件(common/read_data.py)

import yaml  # 用于处理 YAML 文件
import json  # 用于处理 JSON 文件
from configparser import ConfigParser  # 用于处理 INI 配置文件
from common.logger import logger  # 导入日志记录器class MyConfigParser(ConfigParser):"""自定义的 ConfigParser 类,继承自 Python 内置的 ConfigParser。主要用于解决 .ini 文件中的键(option)自动转为小写的问题。"""def __init__(self, defaults=None):# 调用父类 ConfigParser 的构造方法ConfigParser.__init__(self, defaults=defaults)def optionxform(self, optionstr):# 重写 optionxform 方法,使选项名称保持大小写不变return optionstrclass ReadFileData():"""该类用于读取不同格式的文件数据,包括 YAML、JSON 和 INI 配置文件。"""def __init__(self):pass  # 该类的构造方法无特殊初始化操作def load_yaml(self, file_path):"""读取 YAML 文件并解析数据。:param file_path: YAML 文件的路径:return: 解析后的 YAML 数据"""logger.info("加载 {} 文件......".format(file_path))  # 记录日志,指示正在加载 YAML 文件with open(file_path, encoding='utf-8') as f:data = yaml.safe_load(f)  # 使用 safe_load 方法解析 YAML 文件logger.info("读到数据 ==>>  {} ".format(data))  # 记录日志,输出读取的数据return datadef load_json(self, file_path):"""读取 JSON 文件并解析数据。:param file_path: JSON 文件的路径:return: 解析后的 JSON 数据"""logger.info("加载 {} 文件......".format(file_path))  # 记录日志,指示正在加载 JSON 文件with open(file_path, encoding='utf-8') as f:data = json.load(f)  # 解析 JSON 文件logger.info("读到数据 ==>>  {} ".format(data))  # 记录日志,输出读取的数据return datadef load_ini(self, file_path):"""读取 INI 配置文件并解析数据。:param file_path: INI 配置文件的路径:return: 解析后的 INI 数据,转换为字典格式"""logger.info("加载 {} 文件......".format(file_path))  # 记录日志,指示正在加载 INI 文件config = MyConfigParser()  # 创建 MyConfigParser 实例config.read(file_path, encoding="UTF-8")  # 读取 INI 配置文件data = dict(config._sections)  # 将配置文件的 sections 转换为字典格式# print("读到数据 ==>>  {} ".format(data))  # 该行被注释掉,避免调试输出return data# 创建 ReadFileData 类的实例,以便在其他模块中直接使用 data 变量进行文件读取操作
data = ReadFileData()

作用:
读取配置文件(如 setting.ini)、解析 YAML 测试数据,并提供一个统一的接口,使其他模块可以轻松获取配置信息和测试数据。

3. config/:配置管理

[host]
# 测试环境
api_root_url = http://127.0.0.1:5000[mysql]
# MySQL配置
MYSQL_HOST = localhost
MYSQL_PORT = 3306
MYSQL_USER = root
MYSQL_PASSWD = 123456
MYSQL_DB = flask_demo
autocommit: True  # 确保自动提交开启

作用:
存储环境变量、数据库连接信息等
让配置可修改、可复用

4. core/:请求封装层

core/ 目录是请求封装层,主要负责:

  • 封装 HTTP 请求方法,提供统一的 API 访问接口(rest_client.py)。
  • 定义接口返回的标准格式,方便后续断言(result_base.py)。

4.1 rest_client.py:封装 HTTP 请求

import requests  # 导入requests库,用于发送HTTP请求
import json as complexjson  # 导入json模块并重命名为complexjson,避免与局部变量json冲突
from common.logger import logger  # 导入日志模块,用于记录HTTP请求日志class RestClient():"""RestClient类,封装HTTP请求的方法"""def __init__(self, api_root_url):"""初始化RestClient类:param api_root_url: API的根URL"""self.api_root_url = api_root_url  # 设置API根URLself.session = requests.session()  # 创建一个requests的会话对象,提高请求效率def get(self, url, **kwargs):"""发送GET请求:param url: API接口路径:param kwargs: 其他可选参数(如headers, params等):return: GET请求的响应对象"""return self.request(url, "GET", **kwargs)def post(self, url, data=None, json=None, **kwargs):"""发送POST请求:param url: API接口路径:param data: 表单数据(可选):param json: JSON格式数据(可选):param kwargs: 其他可选参数(如headers等):return: POST请求的响应对象"""return self.request(url, "POST", data, json, **kwargs)def put(self, url, data=None, **kwargs):"""发送PUT请求:param url: API接口路径:param data: 需要更新的数据:param kwargs: 其他可选参数(如headers等):return: PUT请求的响应对象"""return self.request(url, "PUT", data, **kwargs)def delete(self, url, **kwargs):"""发送DELETE请求:param url: API接口路径:param kwargs: 其他可选参数(如headers等):return: DELETE请求的响应对象"""return self.request(url, "DELETE", **kwargs)def patch(self, url, data=None, **kwargs):"""发送PATCH请求:param url: API接口路径:param data: 需要部分更新的数据:param kwargs: 其他可选参数(如headers等):return: PATCH请求的响应对象"""return self.request(url, "PATCH", data, **kwargs)def request(self, url, method, data=None, json=None, **kwargs):"""统一的请求方法:param url: API接口路径:param method: 请求方法(GET, POST, PUT, DELETE, PATCH):param data: 表单数据(可选):param json: JSON格式数据(可选):param kwargs: 其他可选参数(如headers, params等):return: 请求的响应对象"""url = self.api_root_url + url  # 拼接完整的URLheaders = dict(**kwargs).get("headers")  # 获取请求头params = dict(**kwargs).get("params")  # 获取请求参数files = dict(**kwargs).get("files")  # 获取文件上传参数cookies = dict(**kwargs).get("cookies")  # 获取cookies参数# 记录请求日志self.request_log(url, method, data, json, params, headers, files, cookies)# 根据请求方法调用相应的requests方法if method == "GET":return self.session.get(url, **kwargs)if method == "POST":return requests.post(url, data=data, json=json, **kwargs)if method == "PUT":if json:data = complexjson.dumps(json)  # 将json对象转换为字符串return self.session.put(url, data=data, **kwargs)if method == "DELETE":return self.session.delete(url, **kwargs)if method == "PATCH":if json:data = complexjson.dumps(json)  # 将json对象转换为字符串return self.session.patch(url, data=data, **kwargs)def request_log(self, url, method, data=None, json=None, params=None, headers=None, files=None, cookies=None,**kwargs):"""记录HTTP请求日志,方便调试和问题排查:param url: 请求的URL:param method: 请求方法(GET, POST, PUT, DELETE, PATCH):param data: 表单数据(可选):param json: JSON格式数据(可选):param params: URL查询参数(可选):param headers: 请求头(可选):param files: 上传的文件(可选):param cookies: 请求的cookies(可选):param kwargs: 其他可选参数"""logger.info("接口请求地址 ==>> {}".format(url))logger.info("接口请求方式 ==>> {}".format(method))logger.info("接口请求头 ==>> {}".format(complexjson.dumps(headers, indent=4, ensure_ascii=False)))logger.info("接口请求 params 参数 ==>> {}".format(complexjson.dumps(params, indent=4, ensure_ascii=False)))logger.info("接口请求体 data 参数 ==>> {}".format(complexjson.dumps(data, indent=4, ensure_ascii=False)))logger.info("接口请求体 json 参数 ==>> {}".format(complexjson.dumps(json, indent=4, ensure_ascii=False)))logger.info("接口上传附件 files 参数 ==>> {}".format(files))logger.info("接口 cookies 参数 ==>> {}".format(complexjson.dumps(cookies, indent=4, ensure_ascii=False)))

rest_client.py 封装了 GET、POST、PUT、DELETE 请求,提供一个 RestClient 类,让其他模块可以直接调用 HTTP 请求方法,而不需要每次都手写 requests.get() 或 requests.post()。

4.2 result_base.py:封装接口返回结果

class ResultBase:"""结果基类,用于定义接口返回结果的标准结构。该类可以在后续扩展时添加通用的返回数据处理逻辑。"""pass

result_base.py 负责解析接口返回的 JSON 数据,并提供统一的访问方式,让测试用例更加简洁。

5.data/:测试数据管理

作用:
让测试用例数据分离,便于维护
支持数据驱动,自动化测试多个场景

6. operation/:业务封装层

from core.result_base import ResultBase
from api.user import user
from common.logger import loggerdef get_all_user_info():"""获取全部用户信息:return: 自定义的关键字返回结果 result"""result = ResultBase()  # 创建ResultBase对象,存储返回结果res = user.list_all_users()  # 调用API获取全部用户信息result.success = False  # 默认成功标志为Falseif res.json()["code"] == 0:  # 判断返回码是否为0result.success = True  # 如果返回码为0,表示成功else:result.error = "接口返回码是 【 {} 】, 返回信息:{} ".format(res.json()["code"], res.json()["msg"])  # 错误信息result.msg = res.json()["msg"]  # 记录返回消息result.response = res  # 记录完整的响应return result  # 返回封装的结果def get_one_user_info(username):"""获取单个用户信息:param username:  用户名:return: 自定义的关键字返回结果 result"""result = ResultBase()  # 创建ResultBase对象res = user.list_one_user(username)  # 获取单个用户信息result.success = False  # 默认成功标志为Falseif res.json()["code"] == 0:result.success = True  # 成功时设置为Trueelse:result.error = "查询用户 ==>> 接口返回码是 【 {} 】, 返回信息:{} ".format(res.json()["code"], res.json()["msg"])  # 错误信息result.msg = res.json()["msg"]result.response = reslogger.info("查看单个用户 ==>> 返回结果 ==>> {}".format(result.response.text))  # 记录日志return resultdef register_user(username, password, telephone, sex="", address=""):"""注册用户信息:param username: 用户名:param password: 密码:param telephone: 手机号:param sex: 性别:param address: 联系地址:return: 自定义的关键字返回结果 result"""result = ResultBase()  # 创建ResultBase对象json_data = {  # 请求体内容"username": username,"password": password,"sex": sex,"telephone": telephone,"address": address}header = {  # 请求头"Content-Type": "application/json"}res = user.register(json=json_data, headers=header)  # 调用API进行注册result.success = False  # 默认失败if res.json()["code"] == 0:result.success = True  # 注册成功时标记为Trueelse:result.error = "接口返回码是 【 {} 】, 返回信息:{} ".format(res.json()["code"], res.json()["msg"])  # 错误信息result.msg = res.json()["msg"]result.response = reslogger.info("注册用户 ==>> 返回结果 ==>> {}".format(result.response.text))  # 记录日志return resultdef login_user(username, password):"""登录用户:param username: 用户名:param password: 密码:return: 自定义的关键字返回结果 result"""result = ResultBase()  # 创建ResultBase对象payload = {  # 登录请求参数"username": username,"password": password}header = {"Content-Type": "application/x-www-form-urlencoded"}res = user.login(data=payload, headers=header)  # 调用API进行登录result.success = False  # 默认失败if res.json()["code"] == 0:result.success = True  # 登录成功时标记为True# result.token = res.json()["login_info"]["token"]  # 存储登录令牌else:result.error = "接口返回码是 【 {} 】, 返回信息:{} ".format(res.json()["code"], res.json()["msg"])  # 错误信息result.msg = res.json()["msg"]result.response = reslogger.info("登录用户 ==>> 返回结果 ==>> {}".format(result.response.text))  # 记录日志return resultdef update_user(id, admin_user, new_password, new_telephone, token, new_sex="", new_address=""):"""根据用户ID,修改用户信息:param id: 用户ID:param admin_user: 当前操作的管理员用户:param new_password: 新密码:param new_telephone: 新手机号:param token: 当前管理员用户的token:param new_sex: 新性别:param new_address: 新联系地址:return: 自定义的关键字返回结果 result"""result = ResultBase()  # 创建ResultBase对象header = {"Content-Type": "application/json"}json_data = {  # 请求体内容"admin_user": admin_user,"password": new_password,"token": token,"sex": new_sex,"telephone": new_telephone,"address": new_address}res = user.update(id, json=json_data, headers=header)  # 调用API进行用户信息更新result.success = False  # 默认失败if res.json()["code"] == 0:result.success = True  # 更新成功时标记为Trueelse:result.error = "接口返回码是 【 {} 】, 返回信息:{} ".format(res.json()["code"], res.json()["msg"])  # 错误信息result.msg = res.json()["msg"]result.response = reslogger.info("修改用户 ==>> 返回结果 ==>> {}".format(result.response.text))  # 记录日志return resultdef delete_user(username, admin_user, token):"""根据用户名,删除用户信息:param username: 用户名:param admin_user: 当前操作的管理员用户:param token: 当前管理员用户的token:return: 自定义的关键字返回结果 result"""result = ResultBase()  # 创建ResultBase对象json_data = {  # 请求体内容"admin_user": admin_user,"token": token,}header = {"Content-Type": "application/json"}res = user.delete(username, json=json_data, headers=header)  # 调用API进行用户删除result.success = False  # 默认失败if res.json()["code"] == 0:result.success = True  # 删除成功时标记为Trueelse:result.error = "接口返回码是 【 {} 】, 返回信息:{} ".format(res.json()["code"], res.json()["msg"])  # 错误信息result.msg = res.json()["msg"]result.response = reslogger.info("删除用户 ==>> 返回结果 ==>> {}".format(result.response.text))  # 记录日志return result

业务api封装,供测试用例调用。

7. 测试报告展示

运行用例后,在项目根目录下,执行命令启动 allure 服务:

allure serve ./testcases/api_test/report

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

相关文章:

Python+Requests+Pytest+YAML+Allure接口自动化框架

GitHub源码地址(详细注释):源码 调试项目python自主搭建:附项目源码 一、项目介绍 本项目是基于 PythonRequestsPytestYAMLAllure 搭建的 接口自动化测试框架,用于对 REST API 进行测试。 框架的主要特点包括&#…...

如何解决Redis缓存异常问题(雪崩、击穿、穿透)

引言 Redis作为一种高性能的内存数据库,被广泛应用于缓存系统的构建中。然而,在实际应用过程中,我们常常会遇到三种典型的缓存异常问题:缓存雪崩、缓存击穿和缓存穿透。这些问题如果处理不当,可能会导致系统性能下降&…...

如何使用 Postman 进行接口测试?

使用 Postman 这一工具,可以轻松地进行接口测试。以下是一份简单的使用教程,帮助你快速上手。 Postman 接口测试教程:详细步骤及操作技巧...

记一次线上环境JAR冲突导致程序报错org.springframework.web.util.NestedServletException

一、问题描述 有个文件导入功能,用到了Hutool 的加密解密功能,本地运行完全可以,但是线上报错:“org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.NoClassDefFou…...

VLAN实验

一:实验拓扑 二:实验需求 1、PC1和PC3所在接口为access接口,属于VLAN 2 2、PC2/4/5/6处于同一网段 其中PC2可以访问PC4/5/6 PC4可以访问PC5不能访问PC6 PC5不能访问PC6 3、PC1/3和PC2/4/5/6不在一个网段,且可以正常通讯 4、…...

FPGA中串行执行方式之状态机

FPGA中串行执行方式之状态机 在FPGA中,默认情况下,逻辑是并行执行的,因为FPGA的硬件资源是并行的。然而,在某些情况下,你可能需要某一段逻辑以串行方式执行。这可以通过以下几种方法实现:使用状态机(Finite State Machine, FSM)​、使用计数器控制、使用流水线(Pipel…...

【常用的中间件】

中间件(Middleware)是位于客户端和服务器之间的软件层,用于处理客户端请求和服务器响应之间的各种任务。中间件可以提供多种功能,如负载均衡、消息队列、缓存、身份验证等。以下是常用的中间件及其作用: 1. 消息队列中…...

spring - 十二种事务失效场景

目录 ​编辑 一、方法内部调用 1、原理: 2、结论: 3、解决方法: 1. 增加一个service,把一个事务的方法移到新增加的service方法里面,然后进行注入再调用 2. 在自己类中注入自己 3. 通过AopContentent 二、访问权限不是pubilc 三、方法用final修饰 四、没有被spr…...

python脚本处理excel文件

1.对比perl和python 分别尝试用perl和python处理excel文件,发现perl的比较复杂,比如说read excel就有很多方式 Spreadsheet::Read use Spreadsheet::ParseExcel 不同的method,对应的取sheet的cell方式也不一样。更复杂的是处理含有中文内…...

C#基础学习(二)C#数组生存手册:从入门到“血压拉满“的奇妙旅程

作为一只C#萌新,当你试图用数组装下整个世界时,系统可能会温柔地弹出一句**"Index was outside the bounds of the array."**。别慌!这份求生指南将用段子教你玩转数组 一、数组是什么 数组简单来说就是由相同元素组成的一个集合&a…...

MySQL 性能优化方向

MySQL 性能优化是一个系统性的工作,涉及数据库设计、查询优化、索引优化、硬件配置等多个方面。以下是 MySQL 性能优化的主要方向和具体优化方案: 一、数据库设计优化 1. 合理设计表结构 规范化设计:避免数据冗余,确保数据一致性。适度反规范化:在查询频繁的场景下,适当…...

2025年- G26-Lc100-57.插入间隔(max、min)--java版

1.题目描述 题目翻译: 给定一个不重叠的区间阵列 intervals,其中intervals[i] [starti, endi]表示第i一个区间的起始位置和结束位置,并且intervals 按照起始位置starti升序排序。 另外,给定一个新的区间newInterval [start, e…...

Burp Suite HTTPS解密原理

HTTPS HTTPS是在HTTP的基础上增加了SSL/TLS协议,提供了数据的加密、完整性校验和身份认证等安全保障。HTTPS的工作过程可以分为两个阶段:握手阶段和数据传输阶段。 流程如下图所示: 通过上面的图可以看到,在TCP建立连接后会发起…...

【ESP32S3】esp32获取串口数据并通过http上传到前端

通过前面的学习(前面没发过,因为其实就是跑它的demo)了解到串口配置以及开启线程实现功能的工作流程,与此同时还有esp32作为STA节点,将数据通过http发送到服务器。 将这两者联合 其实是可以得到一个:esp32获…...

怎么查看linux是Ubuntu还是centos

要确定你的Linux系统是基于Ubuntu还是CentOS,可以通过几种不同的方法来进行判断。下面是一些常用的方法: 要快速判断 Linux 系统是 Ubuntu 还是 CentOS,可通过以下方法综合验证: 一、查看系统信息文件 1. /etc/os-release 文件…...

Qt进程间通信:QSharedMemory 使用详解

1. 什么是 QSharedMemory? QSharedMemory 是 Qt 中用于进程间共享内存的类。它允许多个进程共享一块内存区域,从而避免数据传输时的 IO 操作,提高通信速度。通过共享内存,多个进程可以直接读写这块内存,而无需经过文件…...

【day1】数据结构刷题 链表

一 反转链表 206. 反转链表 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 示例 1: 输入:head [1,2,3,4,5] 输出:[5,4,3,2,1]示例 2: 输入:head [1,2] 输出:[2,1]…...

使用redis设置店铺状态

知识点: 将前端传过来的status(0,1)通过redis对象以key,values值的形式存放在redis中。 #设置店铺状态 redisTemplate.opsForValue().set(KEY,status); #获取店铺状态 Integer status (Integer) redisTemplate.o…...

基于python+django的商城网站-电子商城管理系统源码+运行

基于 python 开发的电子商城网站,平台采用 B/S 结构,后端采用主流的 Python 语言进行开发,前端采用主流的 Vue.js 进行开发。该系统是给师弟做的课程作业。同学们可以拿去自用。学习问题可以留言哦。 整个平台包括前台和后台两个部分。 前台…...

深度解读 C 语言运算符:编程运算的核心工具

一、引言 在 C 语言的编程世界中,运算符是构建逻辑与运算的基石,它如同一位指挥家,精准地协调着程序中各种数据的操作与处理。C 语言丰富多样的运算符涵盖了算术、关系、逻辑、位运算、赋值以及其他杂项运算等多个领域,为开发者提…...

docker中间件部署

1.docker安装 # 1.卸载旧版本 yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine# 2.需要的安装包 yum install -y yum-utils# 3.设置镜像的仓库 # 3.1.默认是国外的&#x…...

【Python Cookbook】字符串和文本(二)

字符串和文本(二) 6.字符串忽略大小写的搜索替换7.最短匹配模式8.多行匹配模式9.将 Unicode 文本标准化10.在正则式中使用 Unicode 6.字符串忽略大小写的搜索替换 你需要以忽略大小写的方式搜索与替换文本字符串。 为了在文本操作时忽略大小写&#xf…...

docker pull时报错:https://registry-1.docker.io/v2/

原文:https://www.cnblogs.com/sdgtxuyong/p/18647915 https://www.cnblogs.com/OneSeting/p/18532166 docker 换源,解决连接不上的问题。 编辑以下文件,不存在则创建: vim /etc/docker/daemon.json {"registry-mirrors&qu…...

DeepSeek助力文案,智能音箱如何改变你的生活?

你好,我是三桥君 你有没有为写智能音箱的宣传文案而抓耳挠腮过?三桥君在这方面可是有些感想,今天就来给你唠唠怎么用DeepSeek写出超赞的智能音箱宣传文案。 首先,你得给DeepSeek喂足“料”。这就好比做饭,你得准备好各…...

【机器学习】什么是随机森林?

什么是随机森林? 随机森林(Random Forest)是一种集成学习方法,它通过组合多个决策树来提高预测的准确性和鲁棒性。可以把随机森林看作是“森林”,而森林中的每棵树就是一个决策树。每棵树独立地做出预测,最…...

Nature Machine Intelligence 嵌入式大语言模型使机器人能够在不可预测的环境中完成复杂的任务

近期英国爱丁堡大学发表Nature Machine Intelligence研究工作,提出了一种名为ELLMER(具身大型语言模型支持机器人)的创新框架,通过整合大型语言模型(如GPT-4)、检索增强生成(RAG)、视…...

[特殊字符] 2025蓝桥杯备赛Day13——P10984 [蓝桥杯 2023 国 Python A] 残缺的数字

🔍 2025蓝桥杯备赛Day13——P10984 [蓝桥杯 2023 国 Python A] 残缺的数字 🚀 题目速览 题目难度:⭐⭐⭐(需掌握位运算与组合数学) 考察重点:二进制状态处理、位运算、乘法原理、枚举 P10984 [蓝桥杯 2…...

【AcWing】算法基础课-数学知识

目录 1、质数 1.1 试除法判定质数 暴力解法 优化解法 1.2 分解质因数(试除法) 暴力解法 优化解法 1.3 筛质数 朴素筛法(nlogn) 埃氏筛法(nloglogn) 线性筛法(n) 2、约数 2.1 试除法求约数 2.2 约数个数 2.3 约数之和 2.4 最大公约数 实现方法一 实现方法二 …...

JVM常见概念之条件移动

问题 当我们有分支频率数据时,有什么有趣的技巧可以做吗?什么是条件移动? 基础知识 如果您需要在来自一个分支的两个结果之间进行选择,那么您可以在 ISA 级别做两件不同的事情。 首先,你可以创建一个分支&#xff…...

k8s存储介绍(二)Secret

Kubernetes(K8s)提供了一种安全的方式来存储和管理敏感信息,如密码、OAuth 令牌和 SSH 密钥,这就是 Secret。使用 Secret 可以避免将敏感数据硬编码到 Pod 规范或容器镜像中,从而提高安全性和可管理性。 1. Secret 的…...

Css布局-常规流笔记

https://developer.mozilla.org/zh-CN/docs/Learn/CSS/CSS_layout/Normal_Floworghttps://developer.mozilla.org/zh-CN/docs/Learn/CSS/CSS_layout/Normal_Flow 前言 常规流布局是html元素默认布局,凡是没有设置过css布局的html元素,默认布局方式称为常…...

Linux系统管理与编程08:任务驱动综合应用

兰生幽谷,不为莫服而不芳; 君子行义,不为莫知而止休。 [环境] windows11、centos7.9.2207、zabbix6、MobaXterm、Internet环境 [要求] zabbix6.0安装环境:Lamp(linux httpd mysql8.0 php) [步骤] 3 …...

基于 OCO - 2 氧气 A 带辐射数据与地面台站气压观测数据构建近地面气压监测算法方案

基于 OCO - 2 氧气 A 带辐射数据与地面台站气压观测数据构建近地面气压监测算法方案 一、数据获取与准备 (一)OCO - 2 氧气 A 带辐射数据 数据下载:从 OCO - 2 官方数据发布平台(如 NASA 的相关数据存储库),按照研究所需的时间范围(例如,近 5 年的数据以获取足够的样本…...

Linux centos7 虚拟用户访问脚本

下面是脚本: #!/bin/bash #function:创建 vsftpd 虚拟用户脚本 #author: 20250324 IT小旋风# 判断是否是 root 用户 if [ "$USER" ! "root" ]; thenecho "不是 root 用户,无法进行安装操作"exit 1 fi# 关闭防火墙 system…...

HTTP 协议中请求与响应的详细解析

前言:HTTP(Hypertext Transfer Protocol,超文本传输协议)是用于在互联网上传输超文本的协议 --由一个请求和响应组成,一个完整的 HTTP 请求由请求行(Request Line)、请求头(Headers&…...

Collectors.toMap / list 转 map

前言 略 Collectors.toMap List<User> userList ...; Map<Long, User> userMap userList.stream().collect(Collectors.toMap(User::getUserId, Function.identity()));假如id存在重复值&#xff0c;则会报错Duplicate key xxx, 解决方案 两个重复id中&#…...

根据模板将 Excel 明细数据生成 PDF 文档 | PDF实现邮件合并功能

在日常办公中&#xff0c;我们常常会面临这样的需求&#xff1a;依据特定的模板&#xff0c;把 Excel 里的每一条数据转化为单独的 PDF 文档&#xff0c;且这些 PDF 文档中的部分内容会根据 Excel 数据动态变化。这一功能不仅能高效完成任务&#xff0c;还支持图片的动态替换&a…...

<KeepAlive>和<keep-alive>有什么区别

在不同的前端技术框架里&#xff0c;<KeepAlive> 和 <keep-alive> 有着不同的含义与使用场景&#xff0c;下面分别从 Vue 2 和 Vue 3 来为你详细介绍它们的区别。 Vue 2 中的 <keep-alive> 在 Vue 2 里&#xff0c;<keep-alive> 属于内置组件&#x…...

vscode正则表达式使用

小标题 ^\d.\d.\d\s.*$ ^表示匹配字符串的开头。\d\.\d\.\d表示匹配一到多个数字&#xff0c;接着一个小数点&#xff0c;再接着一到多个数字&#xff0c;然后又一个小数点和一到多个数字&#xff0c;用来匹配类似 “2.1.1” 这样的标题号部分。\s表示匹配一个空格。.*表示匹配…...

【LeetCode 题解】算法:4.寻找两个正序数组的中位数

1. 引言&#xff1a;挑战 LeetCode 经典算法题 在算法这片广袤无垠的天地里&#xff0c;一道道经典题目宛如夜空中熠熠生辉的星辰&#xff0c;持续吸引着开发者们投身其中&#xff0c;不断探索。今天&#xff0c;我们继续将目光聚焦于 LeetCode 平台上一道极具代表性的题目&am…...

2025.03.23【前沿工具】| CellPhoneDB:基因网络分析与可视化的利器

文章目录 1. CellPhoneDB工具简介2. CellPhoneDB的安装方法3. CellPhoneDB常用命令 1. CellPhoneDB工具简介 在单细胞生物学的迅猛发展中&#xff0c;理解细胞间的通讯机制对于揭示组织功能和疾病状态至关重要。CellPhoneDB工具&#xff0c;作为一个专门设计用来分析单细胞转录…...

Excel(进阶篇):powerquery详解、PowerQuery的各种用法,逆透视表格、双行表头如何制作透视表、不规则数据如何制作数据透视表

目录 PowerQuery工具基础修改现有数据理规则PowerQuery抓取数据的两种方式多文件合并透视不同表结构多表追加数据透视追加与合并整理横向表格:逆透视 数据用拆分工具整理数据算账龄 不等步长值组合合并文件夹中所有文件PowerQuery处理CSV文件双行表头、带合并单元格如何做数据…...

【WebGIS教程2】Web服务与地理空间服务解析

前言&#xff1a; 在万物互联的时代&#xff0c;Web服务作为跨平台协作的基石&#xff0c;正推动地理信息领域向开放共享迈进。地理空间Web服务通过标准化协议&#xff08;如WMS、WFS&#xff09;与松耦合架构&#xff0c;打破传统GIS的封闭性&#xff0c;实现数据与功能的无缝…...

[250325] Claude AI 现已支持网络搜索功能!| ReactOS 0.4.15 发布!

目录 Claude AI 现已支持网络搜索功能&#xff01;ReactOS 0.4.15 发布&#xff01; Claude AI 现已支持网络搜索功能&#xff01; 近日&#xff0c;Anthropic 公司宣布&#xff0c;其 AI 助手 Claude 现在可以进行网络搜索&#xff0c;为用户提供更及时、更相关的回复。这项新…...

gitee第三方登录获取openid | python+Django |已跑通

注&#xff1a;此项目根据美多改编&#xff0c;qq第三方需要备案gitee不用 一、获取appid和appsecret 点击右侧账号设置 左侧菜单栏数据管理里有第三方应用 点击创建应用&#xff0c;根据你的具体情况设置 二、以下是事例代码&#xff0c;根据需要修改即可 setting.py #QQ登…...

Enovia许可分析的自动化解决方案

随着企业产品生命周期管理&#xff08;PLM&#xff09;需求的不断演变&#xff0c;Enovia许可分析已成为确保资源优化和合规性的关键环节。然而&#xff0c;传统的手动许可分析方法往往效率低下、易出错&#xff0c;并且难以应对大规模数据。为了解决这一挑战&#xff0c;Enovi…...

【模拟面试】计算机考研复试集训(第十四天)

文章目录 前言一、专业面试1、进程调度中的轮转调度&#xff08;Round Robin&#xff09;如何实现&#xff1f;时间片大小对系统性能有何影响&#xff1f;2、动态规划的核心思想是什么&#xff1f;举一例说明其与分治法的区别。3、事务的ACID特性中&#xff0c;“隔离性” 如何…...

ambiq apollo3 ADC实例程序注释

#include "am_mcu_apollo.h" // Apollo MCU 外设寄存器定义和HAL库 #include "am_bsp.h" // 板级支持包&#xff08;引脚定义、LED函数等&#xff09; #include "am_util.h" // 通用工具函数&#xff08;如printf重…...

ECharts实现数据可视化

ECharts实现数据可视化 一、Echarts的简介二、Echarts使用教程1.下载echarts.min.js文件2.编写echarts代码&#xff08;1&#xff09;创建渲染实列&#xff08;2&#xff09;修改option达到预期的效果&#xff08;3&#xff09;创建配置项到实例中 三、Echarts的基础配置四、前…...

Json冲突崩溃问题

在一个项目中同时使用RapidJSON库后崩溃了。。。。 --- ### **一、潜在问题分析** 1. **符号重复定义&#xff08;ODR冲突&#xff09;** - **原因**&#xff1a;若您的库和上位机主程序均静态链接了RapidJSON&#xff08;如编译为.a或.lib&#xff09;&#xff0c;或通…...