python - 在linux上编译py文件为【.so】文件部署项目运行
python - 在linux上编译py文件为【.so】文件,可通过主文件直接执行
一. 前言
在Python中,通常不直接将Python代码编译为.so(共享对象)文件来执行,因为.so文件是编译后的二进制代码,通常用于C或C++等语言,并且它们被设计为可以被Python(通过C API)或其他语言(如C或C++)动态加载和执行。
二.打包编译项目
准备工作
一般linux上都会有GCC编译器,如若没有请先安装
1.安装Cython
pip install cython
2.将以下的脚本放在deploy目录下,项目所有文件放在project下面即可
1.编译为.c文件的代码
创建一个setup_cmd.py
文件
import logging
import osfrom setuptools import setup
from Cython.Build import cythonize# ============================== 配置日志 ===============================
# 定义日志文件的名称
log_filename = 'setup_cmd.log'# 创建一个日志记录器
logger = logging.getLogger()
logger.setLevel(logging.INFO) # 设置日志级别为 INFO# 创建一个文件处理器,并设置级别为 INFO
file_handler = logging.FileHandler(log_filename, encoding='utf-8') # 指定编码为 utf-8
file_handler.setLevel(logging.INFO)# 创建一个流处理器(控制台输出),并设置级别为 INFO
stream_handler = logging.StreamHandler()
stream_handler.setLevel(logging.INFO)# 创建日志格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)
stream_handler.setFormatter(formatter)# 将处理器添加到日志记录器
logger.addHandler(file_handler)
logger.addHandler(stream_handler)# ============================== 配置日志 ===============================
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # 设置 BASE_DIR
logger.info(f"BASE_DIR -> {BASE_DIR}\n")# 获取需要编译的文件列表
def get_py_files(directory, exclude_folders, exclude_file_list):py_files = []for root, dirs, files in os.walk(directory):for d in dirs:if d in exclude_folders:dirs.remove(d)for file in files:if file in exclude_file_list:logger.info(f"不需要编译文件:[{file}] 在 {exclude_file_list} 中!")continueif file.endswith('.py') and '-' not in file:py_files.append(os.path.join(root, file))logger.info(f'py_files -> {py_files}')logger.info(f'py_files count -> {len(py_files)}')return py_filesexclude_folders = ['tests', '.git', '.idea', '__pycache__', 'a-deploy', 'deploy']
exclude_file_list = ['app.py']# 1.编译打包
file_list = get_py_files(BASE_DIR, exclude_folders, exclude_file_list)
# 单个文件编译或多个文件
# file_list = ['/opt/pkg/project/dev/service/sessionService/service_impl/nw_session_history.py']
setup(ext_modules=cythonize(file_list, language_level=3), # 使用 Python 3 的语言级别
)
1.在linux环境下可直接执行文件
python3 setup_cmd.py
2.windows上直接使用命令执行
python3 setup_cmd.py build_ext --inplace
2.将.c文件转化为.so文件
创建setup_compile_file.py
文件
主要是将以下命令拆解执行
gcc -pthread -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -I/usr/local/include/python3.11 -c /opt/pkg/project/dev/base/utils/handle_tasks.c -o build/temp.linux-x86_64-cpython-311/opt/pkg/project/dev/base/utils/handle_tasks.o
gcc -pthread -shared build/temp.linux-x86_64-cpython-311/opt/pkg/project/dev/base/utils/handle_tasks.o -o build/lib.linux-x86_64-cpython-311/handle_tasks.cpython-311-x86_64-linux-gnu.so
代码如下,参考函数:compile_c_files
# -*- coding: utf-8 -*-
import logging
import os
import shutil
import subprocessfrom setuptools import setup
from Cython.Build import cythonizeimport osfrom concurrent.futures import ThreadPoolExecutor, wait, ALL_COMPLETEDexecutor = ThreadPoolExecutor(max_workers=50)# ============================== 配置日志 ===============================
# 定义日志文件的名称
log_filename = 'setup_compile_file.log'# 创建一个日志记录器
logger = logging.getLogger()
logger.setLevel(logging.INFO) # 设置日志级别为 INFO# 创建一个文件处理器,并设置级别为 INFO
file_handler = logging.FileHandler(log_filename, encoding='utf-8') # 指定编码为 utf-8
file_handler.setLevel(logging.INFO)# 创建一个流处理器(控制台输出),并设置级别为 INFO
stream_handler = logging.StreamHandler()
stream_handler.setLevel(logging.INFO)# 创建日志格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)
stream_handler.setFormatter(formatter)# 将处理器添加到日志记录器
logger.addHandler(file_handler)
logger.addHandler(stream_handler)
# ============================== 配置日志 ===============================# BASE_DIR = os.getcwd()
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # 设置 BASE_DIR
logger.info(f"BASE_DIR -> {BASE_DIR}\n")executor = ThreadPoolExecutor(max_workers=10) # 根据需要调整线程数# 获取需要编译的文件列表
def get_py_files(directory, exclude_folders, exclude_file_list):py_files = []for root, dirs, files in os.walk(directory):for d in dirs:if d in exclude_folders:dirs.remove(d)for file in files:if file in exclude_file_list:logger.info(f"不需要编译文件:[{file}] 在 {exclude_file_list} 中!")continueif file.endswith('.py') and '-' not in file:py_files.append(os.path.join(root, file))logger.info(f'py_files -> {py_files}')logger.info(f'py_files count -> {len(py_files)}')return py_files# 编译扩展模块
def compile_pkg(file_list):setup(ext_modules=cythonize(file_list, language_level=3), # 使用 Python 3 的语言级别)subprocess.run(['python3', 'setup_compile_file.py', 'build_ext', '--inplace'])#
def copy_compiled_files(source_dir, target_dir, exclude_folders, exclude_file_list):""" 拷贝处理编译好的文件 """if os.path.exists(target_dir):shutil.rmtree(target_dir)logger.info(f"已删除旧的目标文件夹: {target_dir}")os.makedirs(target_dir)logger.info(f"已创建新的目标文件夹: {target_dir}")ans = 0# 遍历源文件夹 for root, dirs, files in os.walk(source_dir):# 过滤掉要排除的文件夹 dirs[:] = [d for d in dirs if d not in exclude_folders]# 遍历当前文件夹中的文件for file in files:try:if file in exclude_file_list:logger.info(f"不拷贝文件:[{file}] 在 exclude_file_list:{exclude_file_list} 中!")continue# 构造源和目标文件路径src_file = os.path.join(root, file)rel_path = os.path.relpath(root, source_dir)dst_file = os.path.join(target_dir, rel_path, file)# 确保目标文件夹存在os.makedirs(os.path.dirname(dst_file), exist_ok=True)# 拷贝文件shutil.copy2(src_file, dst_file)ans += 1logger.info(f'文件拷贝成功[src_file]:{src_file} -> [dst_file]:{dst_file}')except Exception as e:logger.info(f'文件拷贝异常:file:{file} -> error:{e}')logger.info(f"已成功拷贝编译文件,数量:{ans}")def delete_specific_files(folder, extensions, exclude_file_list):"""在指定文件夹中删除所有以extensions中指定的扩展名结尾的文件。:param folder: 文件夹路径:param extensions: 要删除的文件扩展名列表"""# 遍历文件夹logger.info(f"")ans = 0for root, dirs, files in os.walk(folder):for file in files:if file in exclude_file_list:logger.info(f"不删除文件:[{file}] 在 exclude_file_list:{exclude_file_list} 中!")continueif file.endswith(tuple(extensions)):os.remove(os.path.join(root, file))logger.info(f"已删除含有 {extensions} 的文件: {os.path.join(root, file)}")ans += 1logger.info(f"已删除以{extensions}结尾的文件数量:{ans}")def compile_c_files(target_dir, extensions, exclude_folders, exclude_file_list):"""编译文件(linux下的命令)gcc -pthread -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -I/usr/local/include/python3.11 -c /opt/pkg/project/dev/base/utils/handle_tasks.c -o build/temp.linux-x86_64-cpython-311/opt/pkg/project/dev/base/utils/handle_tasks.ogcc -pthread -shared build/temp.linux-x86_64-cpython-311/opt/pkg/project/dev/base/utils/handle_tasks.o -o build/lib.linux-x86_64-cpython-311/handle_tasks.cpython-311-x86_64-linux-gnu.so"""# 遍历文件夹ans = 0futures = []for root, dirs, files in os.walk(target_dir):for file in files:if file in exclude_file_list:logger.info(f"文件:{file} 在 exclude_file_list:{exclude_file_list} 中,不需要编译!")continueif file.endswith(tuple(extensions)):c_path = os.path.join(root, file)file_name = file.split('.')[0]# o_path = root + '/' + file_name + '.o'o_path = os.path.join(root, file_name + '.o')# so_path = root + '/' + file_name + '.cpython-311-x86_64-linux-gnu.so'so_path = os.path.join(root, file_name + '.cpython-311-x86_64-linux-gnu.so')logger.info(f'c_path - > {c_path}')logger.info(f'o_path - > {o_path}')logger.info(f'so_path - > {so_path}')future = executor.submit(compile_file_to_so, c_path, o_path, so_path)futures.append(future)ans += 1logger.info(f'complied count -----> {ans}')# 等待所有任务完成wait(futures, return_when=ALL_COMPLETED)logger.info(f"已编译文件数量:{ans}")def compile_file_to_so(c_path, o_path, so_path):os.system(f"gcc -pthread -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -I/usr/local/include/python3.11 -c {c_path} -o {o_path}")os.system(f"gcc -pthread -shared {o_path} -o {so_path}")logger.info(f'File success compiled to - > {so_path}')def main():exclude_folders = ['tests', '.git', '.idea', '__pycache__', 'a-deploy', 'deploy']exclude_file_list = ['app.py', 'app.c']logger.info(f'项目编译打包开始,源码文件路劲:{BASE_DIR}\n')# try:# # 单个文件编译或多个文件# # file_list = ['/opt/pkg/project/dev/service/sessionService/service_impl/nw_session_history.py']## # 1.编译打包# file_list = get_py_files(BASE_DIR, exclude_folders, exclude_file_list)# compile_pkg(file_list)# ...# except Exception as e:# logger.info(f'Exception:{e}')source_dir = BASE_DIRtarget_dir = os.path.join(BASE_DIR, 'deploy', 'dist')# 清除['.c']文件extensions = ['.c']logger.info(f'开始清除项目中含有{extensions}结尾的文件 [target_dir]:{target_dir}\n')delete_specific_files(target_dir, extensions, exclude_file_list)logger.info(f'结束清除项目中含有{extensions}结尾的文件 [target_dir]:{target_dir}\n')# 2.复制编译好的文件logger.info(f'复制拷贝项目开始 [source_dir]:{source_dir} -> [target_dir]:{target_dir}\n')copy_compiled_files(source_dir, target_dir, exclude_folders, ['app.c'])logger.info(f'复制拷贝项目结束 [source_dir]:{source_dir} -> [target_dir]:{target_dir}\n')# # 3.删除py文件# extensions = ['.py']# logger.info(f'开始删除拷贝项目中含有{extensions}结尾的文件 [target_dir]:{target_dir}\n')# delete_specific_files(target_dir, extensions, exclude_file_list)# logger.info(f'结束删除拷贝项目中含有{extensions}结尾的文件 [target_dir]:{target_dir}\n')# 4.编译项目['.c']文件 -> ['.so', 'pyd']compile_extensions = ['.c']logger.info(f"开始编译项目{compile_extensions}文件 -> ['.so', 'pyd']\n")compile_c_files(target_dir, compile_extensions, exclude_folders, exclude_file_list)logger.info(f"结束编译项目{compile_extensions}文件 -> ['.so', 'pyd']\n")logger.info(f'项目编译处理完成,源码文件路劲:{source_dir}\n')logger.info(f'项目编译处理完成,编译打包文件路劲:{target_dir}\n')if __name__ == '__main__':main()
3.清理编译后的项目文件
创建clean_compile_file.py
文件
# -*- coding: utf-8 -*-
import loggingimport osfrom concurrent.futures import ThreadPoolExecutorexecutor = ThreadPoolExecutor(max_workers=50)# ============================== 配置日志 ===============================
# 定义日志文件的名称
log_filename = 'setup_compile_file.log'# 创建一个日志记录器
logger = logging.getLogger()
logger.setLevel(logging.INFO) # 设置日志级别为 INFO# 创建一个文件处理器,并设置级别为 INFO
file_handler = logging.FileHandler(log_filename, encoding='utf-8') # 指定编码为 utf-8
file_handler.setLevel(logging.INFO)# 创建一个流处理器(控制台输出),并设置级别为 INFO
stream_handler = logging.StreamHandler()
stream_handler.setLevel(logging.INFO)# 创建日志格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)
stream_handler.setFormatter(formatter)# 将处理器添加到日志记录器
logger.addHandler(file_handler)
logger.addHandler(stream_handler)
# ============================== 配置日志 ===============================# BASE_DIR = os.getcwd()
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # 设置 BASE_DIR
logger.info(f"BASE_DIR -> {BASE_DIR}\n")def delete_specific_files(folder, extensions, exclude_file_list):"""在指定文件夹中删除所有以extensions中指定的扩展名结尾的文件。:param folder: 文件夹路径:param extensions: 要删除的文件扩展名列表"""# 遍历文件夹logger.info(f"")ans = 0for root, dirs, files in os.walk(folder):for file in files:if file in exclude_file_list:logger.info(f"不删除文件:[{file}] 在 exclude_file_list:{exclude_file_list} 中!")continueif file.endswith(tuple(extensions)):os.remove(os.path.join(root, file))logger.info(f"已删除含有 {extensions} 的文件: {os.path.join(root, file)}")ans += 1logger.info(f"已删除以{extensions}结尾的文件数量:{ans}")def main():exclude_folders = ['tests', '.git', '.idea', '__pycache__', 'a-deploy', 'deploy']exclude_file_list = ['app.py', 'app.c']logger.info(f'========= 项目编译文件清理完成开始 ========\n')target_dir = os.path.join(BASE_DIR, 'deploy', 'dist')# 删除py文件extensions = ['.py', '.o', '.pyd', '.c']logger.info(f'开始删除拷贝项目中含有{extensions}结尾的文件 [target_dir]:{target_dir}\n')delete_specific_files(target_dir, extensions, exclude_file_list)logger.info(f'结束删除拷贝项目中含有{extensions}结尾的文件 [target_dir]:{target_dir}\n')# # 删除源码下的['.so', 'pyd', '.c']文件# src_extensions = ['.so', 'pyd', '.c']# logger.info(f"开始删除源码下的{src_extensions}文件\n")# delete_specific_files(source_dir, src_extensions)# logger.info(f"结束删除源码下的{src_extensions}文件\n")logger.info(f'========= 项目编译文件清理完成!=========\n')if __name__ == '__main__':main()
其他操作
清理源代码下的.c文件(可选)
clean_code_c_file.py
# -*- coding: utf-8 -*-
import loggingimport osfrom concurrent.futures import ThreadPoolExecutorexecutor = ThreadPoolExecutor(max_workers=50)# ============================== 配置日志 ===============================
# 定义日志文件的名称
log_filename = 'setup_compile_file.log'# 创建一个日志记录器
logger = logging.getLogger()
logger.setLevel(logging.INFO) # 设置日志级别为 INFO# 创建一个文件处理器,并设置级别为 INFO
file_handler = logging.FileHandler(log_filename, encoding='utf-8') # 指定编码为 utf-8
file_handler.setLevel(logging.INFO)# 创建一个流处理器(控制台输出),并设置级别为 INFO
stream_handler = logging.StreamHandler()
stream_handler.setLevel(logging.INFO)# 创建日志格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)
stream_handler.setFormatter(formatter)# 将处理器添加到日志记录器
logger.addHandler(file_handler)
logger.addHandler(stream_handler)
# ============================== 配置日志 ===============================# BASE_DIR = os.getcwd()
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # 设置 BASE_DIR
logger.info(f"BASE_DIR -> {BASE_DIR}\n")def delete_specific_files(folder, extensions, exclude_file_list):"""在指定文件夹中删除所有以extensions中指定的扩展名结尾的文件。:param folder: 文件夹路径:param extensions: 要删除的文件扩展名列表"""# 遍历文件夹logger.info(f"")ans = 0for root, dirs, files in os.walk(folder):for file in files:if file in exclude_file_list:logger.info(f"不删除文件:[{file}] 在 exclude_file_list:{exclude_file_list} 中!")continueif file.endswith(tuple(extensions)):os.remove(os.path.join(root, file))logger.info(f"已删除含有 {extensions} 的文件: {os.path.join(root, file)}")ans += 1logger.info(f"已删除以{extensions}结尾的文件数量:{ans}")def main():exclude_folders = ['tests', '.git', '.idea', '__pycache__', 'a-deploy', 'deploy']exclude_file_list = ['app.py', 'app.c']logger.info(f'========= 项目编译文件清理完成开始 ========\n')source_dir = BASE_DIR# 删除源码下的['.so', 'pyd', '.c']文件src_extensions = ['.c']logger.info(f"开始删除源码下的{src_extensions}文件\n")delete_specific_files(source_dir, src_extensions, exclude_file_list)logger.info(f"结束删除源码下的{src_extensions}文件\n")logger.info(f'========= 项目源码文件清理完成!=========\n')if __name__ == '__main__':main()
shell脚本
start_setup.sh
#!/bin/bashecho "开始执行 setup_cmd.py ..."
python3 setup_cmd.py
echo "setup_cmd.py 执行完成!"echo "开始执行 setup_compile_file.py ..."
python3 setup_compile_file.py
if [ $? -eq 0 ]; thenecho "setup_compile_file.py 中的所有任务执行成功完成!"
elseecho "setup_compile_file.py 执行失败或任务未完成,请检查错误。"exit 1
fi# 等待 setup_compile_file.py 中的所有线程完成后,执行 clean_compile_file.py
echo "开始执行 clean_compile_file.py ..."
python3 clean_compile_file.py
if [ $? -eq 0 ]; thenecho "clean_compile_file.py 执行成功!"
elseecho "clean_compile_file.py 执行失败,请检查错误。"exit 1
fiecho "所有脚本执行完毕。"
Cython只是帮助我们将Python代码(或Python风格的代码)转换成了C代码,然后编译成了二进制形式。这个过程并不是传统意义上的“编译Python代码为机器码执行”,而是利用了C的编译效率和Python的易用性之间的平衡。
本文介绍到此结束,希望对你有所帮助!
相关文章:

python - 在linux上编译py文件为【.so】文件部署项目运行
python - 在linux上编译py文件为【.so】文件,可通过主文件直接执行 一. 前言 在Python中,通常不直接将Python代码编译为.so(共享对象)文件来执行,因为.so文件是编译后的二进制代码,通常用于C或C等语言&am…...
SQL_having_pandas_filter
HAVING子句在SQL中用于对分组后的结果进行过滤,它通常与GROUP BY子句一起使用。HAVING子句允许你指定条件来过滤聚合函数的结果,而WHERE子句则用于在分组之前过滤原始数据。 基本语法 SELECT column_name, aggregate_function(column_name) FROM table…...

从软件架构设计角度理解Kafka
网上对于消息中间件的介绍文章比较多,这里我们不再赘述,我们换个思路来理解消息中间件,从软件开发架构的角度来看下消息中间件是如何诞生和演进的。 一、概述 上图中P代表 Provider,C代表Consumer,下同。P和C是一个典型…...

什么是中断?
1.什么是中断 2.中断的重要性 3.中断的上下半部 4.中断处理流程 中断的原则 5.ARM处理器程序运行过程 6.程序被被中断时,怎么保护现场 1.什么是中断 中断是指在 CPU 正常运行期间, 由外部或内部事件引起的一种机制。 当中断发生时,…...

后端(实例)08
设计一个前端在数据库调取数据的表格,并完成基础点击增删改查的功能: 1.首先写一个前端样式(空壳) <!DOCTYPE html> <html> <head> <meta charset"UTF-8"> <title>Insert title here&l…...

【stm32】TIM定时器输出比较-PWM驱动LED呼吸灯/舵机/直流电机
TIM定时器输出比较 一、输出比较简介1、OC(Output Compare)输出比较2、PWM简介3、输出比较通道(高级)4、输出比较通道(通用)5、输出比较模式6、PWM基本结构配置步骤:程序代码:PWM驱动LED呼吸灯 7、参数计算8、舵机简介程序代码&am…...

如何使用ssm实现线上旅游体验系统+vue
TOC ssm691线上旅游体验系统vue 绪论 课题背景 身处网络时代,随着网络系统体系发展的不断成熟和完善,人们的生活也随之发生了很大的变化。目前,人们在追求较高物质生活的同时,也在想着如何使自身的精神内涵得到提升࿰…...

探索JMeterTools:一个Python驱动的JMeter脚本生成器
JMeterTools 简介 JMeterTools 是一个由 Python 编写的开源项目,旨在帮助测试人员快速生成 JMeter 测试脚本。通过简单的 Python API,用户可以方便地定义测试计划、线程组、HTTP 请求等,可以结合接口自动化测试项目,将接口自动化…...

【React】组件通信
1. 组件通信 组件间的数据传递 1.1 父传子 步骤: 父组件传递数据——在子组件标签上绑定属性子组件接收数据——子组件通过props参数接收数据 function Son(props) {return <div>{props.value}</div> }function App() {const value 父组件传给子…...

C++核心编程和桌面应用开发 第七天(运算符重载 智能指针)
目录 1.数组类 2.运算符重载 2.1加号运算符 2.1.1成员函数实现 2.1.2全局函数实现 2.1.3加号重载 2.2左移运算符 2.3递增运算符 2.4指针运算符 2.5赋值运算符 1.数组类 //默认构造函数 MyArray::MyArray() {m_Size 0;m_Capacity 100;pAddress new int[m_Capacity]…...

echarts地图的简单使用
echarts地图的简单使用 文章说明核心源码效果展示源码下载 文章说明 主要介绍echarts地图组件的简单使用,记录为文章,供后续查阅使用 目前只是简单的示例,然后还存在着一些小bug,主要是首个Legend的点击会导致颜色全部不展示的问题…...
Qt 项目优化实践方向
目录 1. 使用智能指针2. 避免在全局或静态作用域中使用裸指针3. 利用Qt的对象树进行资源管理4. 延迟加载和按需加载资源5. 合理使用Qt的资源文件(qrc)6. 监控和调试内存使用7. 优化数据结构8. 减少不必要的资源复制9. 使用缓存机制10. 遵循RAII原则 以下…...

常见的15个:自然语言处理(NLP)实战项目
自然语言处理(NLP)实战项目涵盖了从基础到高级的多个领域,以下是一些常见的NLP实战项目,每个项目都附带了简要的描述和可能用到的技术栈: 1. 文本分类(Text Classification) 描述: 将文本数据…...

CKKS同态加密通用函数近似方法和openFHE实现
摘要 同态加密可以直接在密文上进行运算,尤其是CKKS,可以直接在实数的密文上进行运算。服务器可以利用强大的计算能力,在不泄露用户隐私的情况下,为用户提供便捷的外包运算服务。然而,CKKS只能进行算术运算࿰…...
Webpack 5的新特性:Asset Modules与Dynamic Import
文章目录 Asset ModulesAsset Modules 类型配置示例分析 Dynamic Import动态导入语法配置示例分析 实际案例分析Asset Modules 实际案例Dynamic Import 实际案例 性能优化Asset Modules 性能优化Dynamic Import 性能优化 详细代码分析Asset Modules 代码分析Dynamic Import 代码…...

解释python requests包的timeout
解释python requests包的timeout 哈哈哈。。。。垃圾python又来了 1 问题 你能看懂下面两个timeout的含义就不用看下面的内容了。 requests.get(http://example.com, timeout(2, 5)) requests.get(http://127.0.0.1:5000/api,timeout1)官网解释!!&am…...

蒙语学习快速方法,速记蒙语单词怎么学习更高效!
要高效学习蒙古语和速记单词,首先要掌握基础知识,如字母表和发音规则。接着,专注于学习日常用语和基础词汇,并运用记忆技巧如联想、发音和构词法来帮助记忆。利用专门的学习软件,如“蒙语学习通”,可以提供…...
Vue3组件通信13种方法
在 Vue3 中,组件之间的通信是构建应用程序的关键 1. 父组件向子组件传递数据 (Props)「父组件:」「子组件:」 2. 子组件向父组件传递数据 (Emit)「父组件:」「子组件:」 3. 兄弟组件通信 (Mitt)「发送事件的组件:」「接收事件的组件:」 4. 透传 Attributes ($attrs)「父组件:」…...

Servlet入门:服务端小程序的初试(自己学习整理的资料)
目录 一.前言 二.建立基础结构编辑 三.具体步骤 找到Tomcat文件并打开Tomcat。 在webapps中创建一个自己的文件夹。 在classes中新建一个Java文件。 在lib中导入需要的jar文件包。 配置环境变量 在Java文件的目录下打开cmd并输入 javac -d . HelloServlet.java进行…...
代码随想录算法训练营第三七天| 动态规划:完全背包理论基础 518.零钱兑换II 377. 组合总和 Ⅳ 322. 零钱兑换
今日任务 动态规划:完全背包理论基础 518.零钱兑换II 377. 组合总和 Ⅳ 322. 零钱兑换 518.零钱兑换II 题目链接: . - 力扣(LeetCode) class Solution {public int change(int amount, int[] coins) {int[] dp new int[amount …...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...

springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...
Admin.Net中的消息通信SignalR解释
定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...

大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...

STM32F4基本定时器使用和原理详解
STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...

基于 TAPD 进行项目管理
起因 自己写了个小工具,仓库用的Github。之前在用markdown进行需求管理,现在随着功能的增加,感觉有点难以管理了,所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD,需要提供一个企业名新建一个项目&#…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...