Python项目打包上传PyPI全攻略:从配置到发布实战
1. 从本地脚本到全球共享为什么要把项目上传到PyPI如果你写过Python脚本大概率用过pip install这个命令。从requests到numpy我们每天都在享受PyPIPython Package Index这个全球最大的Python软件仓库带来的便利。但你是否想过自己写的那个解决了某个特定问题、封装了某个好用功能的脚本或模块也能像这些知名库一样被任何人一键安装这就是上传项目到PyPI的意义所在。它远不止是“发布”这么简单。当你把代码打包上传后你的项目就从“本地文件”升级为了一个“可被管理的依赖”。这意味着标准化分发用户无需再手动复制你的代码文件或处理复杂的路径问题一句pip install your-package-name就能搞定所有依赖和环境。版本控制你可以通过PyPI管理项目的不同版本如1.0.01.1.0用户可以根据需要安装或升级特定版本。生态集成你的工具正式成为了Python庞大生态中的一员可以被其他项目轻松引用出现在各种教程、文档和依赖列表中。协作与信任一个规范的PyPI包其元数据作者、许可证、描述、依赖项清晰明了比直接分享源代码zip文件更显专业和可信。最近网络上的高频热词如“pip安装”、“pip镜像”、“pip install各种报错”恰恰反映了Python开发者对包管理的强依赖和常遇到的痛点。作为包的作者理解并走通上传流程不仅能解决自己的分发问题也能更深刻地理解用户端那些“安装失败”背后的原因从而写出兼容性更好、更健壮的包。本文将以一个实战者的视角手把手带你完成从零开始将一个Python项目打包、配置并上传至PyPI官方仓库的全过程。我们会深入每个步骤背后的“为什么”并分享那些官方文档不会写的、从多次实战中踩坑总结出来的经验和技巧。2. 上传前的核心准备理解“包”的构成与规范在动手敲命令之前我们必须先搞清楚一个能被pip成功安装的“包”到底长什么样。很多人以为把一堆.py文件打个压缩包就行这恰恰是第一个大坑。2.1 项目结构不止是源代码一个标准的、适合发布的可安装包其目录结构有明确的约定。假设我们的项目叫做my_awesome_tool一个推荐的结构如下my_awesome_tool/ ├── my_awesome_tool/ # 核心包目录名字通常与项目名一致 │ ├── __init__.py # 使Python将目录视为包可存放包级别代码 │ ├── core.py # 主模块文件 │ └── utils.py # 工具模块文件 ├── tests/ # 测试目录非必须但强烈推荐 │ └── test_core.py ├── docs/ # 文档目录可选 ├── README.md # 项目说明文档至关重要 ├── LICENSE # 开源许可证必须要有 ├── pyproject.toml # 现代构建配置核心文件推荐 ├── setup.cfg # 传统配置方式备用 └── setup.py # 传统入口脚本目前主要起兼容作用关键点解析双层目录结构注意最外层的my_awesome_tool/是项目根目录里面的my_awesome_tool/才是真正的Python包目录。这种结构将项目元文件配置、文档和真正的Python包代码清晰分离。__init__.py这个文件可以是空的但它标志着这是一个“常规包”Regular Package。在Python 3.3中也支持“命名空间包”无需此文件但对于初学者和绝大多数项目保留它是更简单可靠的做法。README.md和LICENSE这两个文件直接影响PyPI页面的展示和用户的使用信心。一个清晰的README说明项目用途、安装方法和简单示例一份明确的LICENSE如MIT Apache 2.0告诉用户他们可以如何使用你的代码。2.2 配置文件的演进从setup.py到pyproject.toml这是近年来PyPI打包领域最大的变化也是很多老教程导致新手困惑的地方。我们需要理解这三种文件的关系。setup.py传统方式这是一个Python脚本通过执行python setup.py sdist bdist_wheel等命令来触发打包。它的核心是调用setuptools.setup()函数并传入一大串参数如name,version,packages等。问题在于它是一段可执行代码这导致构建行为不可重复可能依赖运行时环境且不利于工具静态分析依赖。setup.cfg声明式配置为了解耦配置和代码出现了setup.cfg。它是一个INI格式的静态配置文件setup.py可以变得极其简单只负责读取这个文件。这比纯setup.py好但仍然是setuptools专属的格式。pyproject.toml现代标准推荐这是PEP 518和PEP 621引入的新一代标准。它使用TOML格式是一个与构建工具无关的声明式配置文件。它不仅可以定义项目元数据取代setup.py/setup.cfg的大部分功能还能指定构建本包所需的依赖如setuptools,wheel。pip和build等现代工具都优先使用它。当前最佳实践是使用pyproject.toml作为主配置文件同时保留一个极简的setup.py以兼容一些尚未完全支持新标准的旧工具或工作流。setup.cfg可以不再需要。2.3 编写核心配置文件pyproject.toml详解让我们为my_awesome_tool创建一个完整的pyproject.toml。这是整个打包过程的“大脑”。[build-system] requires [setuptools61.0, wheel] build-backend setuptools.build_meta [project] name my-awesome-tool version 0.1.0 authors [ {name Your Name, email your.emailexample.com}, ] description A brief description of your awesome tool. readme README.md license {text MIT} classifiers [ Programming Language :: Python :: 3, Programming Language :: Python :: 3.7, Programming Language :: Python :: 3.8, Programming Language :: Python :: 3.9, Programming Language :: Python :: 3.10, Programming Language :: Python :: 3.11, License :: OSI Approved :: MIT License, Operating System :: OS Independent, ] keywords [tool, utility, automation] dependencies [ requests2.25.0, click8.0.0, # 一个例子如果你需要命令行界面 ] [project.urls] Homepage https://github.com/yourusername/my_awesome_tool Repository https://github.com/yourusername/my_awesome_tool.git Bug Tracker https://github.com/yourusername/my_awesome_tool/issues [project.optional-dependencies] dev [ pytest6.0, black22.0, flake84.0, ] [tool.setuptools.packages.find] where [.] # 在当前目录下查找包 include [my_awesome_tool*] # 包含所有以此开头的包 exclude [tests*, docs*] # 排除测试和文档目录 [tool.setuptools.package-data] my_awesome_tool [data/*.json, templates/*.txt] # 包含非代码文件逐段解读与避坑指南[build-system]这是最重要的部分之一经常被遗漏。它告诉构建工具如pip或build构建本项目需要什么环境。requires列出了构建依赖build-backend指定了使用哪个后端这里是用setuptools。没有这个部分很多现代构建命令会失败。[project]定义项目的核心元数据。name这是包在PyPI上的唯一标识也是pip install时用的名字。必须全小写可用连字符。确保在PyPI上唯一上传前可先搜索。version遵循语义化版本规范主版本.次版本.修订号。每次上传新版本此号必须递增。description和readme会显示在PyPI项目首页直接影响用户第一印象。classifiers分类器帮助PyPI对项目进行分类。正确设置Python版本和许可证非常重要。dependencies你的包运行时所依赖的其他PyPI包。当用户pip install你的包时这些依赖会被自动安装。务必使用宽松的版本限定如而非严格锁定除非有极特殊原因否则避免给用户带来冲突。[project.optional-dependencies]定义可选依赖组。例如用户可以通过pip install my-awesome-tool[dev]来额外安装开发依赖如测试框架、代码格式化工具。这保持了核心安装的轻量。[tool.setuptools.packages.find]自动发现项目中的包避免在setup.py中手动列出大大减少了配置复杂度。[tool.setuptools.package-data]一个关键但易忽略的配置。如果你的包需要包含非.py文件如图片、数据文件、模板等必须在这里声明否则它们不会被打包进去导致运行时FileNotFoundError。2.4 保留一个极简的setup.py为了最大兼容性我们可以在项目根目录创建一个简单的setup.pyfrom setuptools import setup if __name__ __main__: setup()是的就这么空。它的作用仅仅是作为一个入口当某些旧工具调用python setup.py ...时setuptools会去读取pyproject.toml中的配置。现代流程使用build和twine已经基本不直接依赖它了。3. 构建分发包生成“可安装”的实体配置好之后我们需要将源代码转换成pip能直接安装的格式。主要有两种分发格式sdist (Source Distribution)后缀为.tar.gz的源码归档。包含所有源代码和pyproject.toml等。pip收到后会在用户本地现场构建。兼容性最好但安装可能较慢需要编译步骤。wheel (Built Distribution)后缀为.whl的预构建包。是一种二进制分发格式包含了已编译的字节码和必要的元数据。安装速度极快是当前的首选。分为纯Python WheelUniversal Wheel 适用于任何平台和Python版本和平台特定Wheel如cpython-39-win_amd64.whl。构建工具的选择过去我们常用python setup.py sdist bdist_wheel。但现在官方推荐使用独立的build工具它更干净、更标准。实操步骤安装构建工具pip install build执行构建在项目根目录有pyproject.toml的目录执行python -m build这个命令会做两件事读取pyproject.toml中的[build-system]创建一个独立的临时虚拟环境来安装构建依赖setuptools和wheel。这确保了构建环境的纯净和可重复性是解决“在我机器上能打包在别人机器上不行”问题的关键。依次构建sdist和wheel包。查看成果命令执行成功后会在项目根目录下生成一个dist/文件夹里面应该有两个文件例如my-awesome-tool-0.1.0.tar.gz(sdist)my_awesome_tool-0.1.0-py3-none-any.whl(wheelpy3-none-any表示这是一个兼容任何Python 3、任何操作系统和CPU架构的“通用wheel”)经验之谈务必同时上传sdist和wheel。wheel提供快速安装体验sdist作为备用以防用户平台没有对应的预构建wheel虽然对于纯Python包通用wheel基本覆盖所有情况。有些非常规的安装方式如从特定分支安装也可能依赖sdist。4. 上传到PyPI使用Twine安全发布构建出分发包后我们需要将其上传到PyPI仓库。绝对不要使用旧的setup.py upload命令它已废弃且不安全使用明文传输密码。官方推荐使用twine。4.1 注册PyPI账户并获取令牌访问 https://pypi.org 并注册一个账户。登录后在账户设置中生成一个API令牌。这是上传包的身份凭证。建议为令牌设置适当的“作用域”Scope对于新项目可以创建针对整个账户的令牌或者更安全地为特定项目创建令牌。令牌只显示一次务必立即复制保存到安全的地方如密码管理器。它看起来像pypi-xxxxxxxxxxxx。4.2 使用Twine上传安装Twinepip install twine上传到PyPI生产环境twine upload dist/*执行后twine会提示你输入用户名和密码。用户名请填写__token__密码就是你刚才复制的API令牌包括pypi-前缀。这是使用API令牌的标准方式。使用测试环境强烈推荐首次上传时使用 PyPI提供了一个测试站点 https://test.pypi.org 它的数据库和主站完全独立。你可以先在这里演练整个上传和安装流程。在TestPyPI上注册一个账户可以和主站相同但需要单独注册。生成TestPyPI的API令牌。使用--repository-url参数指定测试仓库twine upload --repository-url https://test.pypi.org/legacy/ dist/*从TestPyPI安装测试pip install --index-url https://test.pypi.org/simple/ my-awesome-tool务必在TestPyPI上完整测试一遍确认包能正常安装、导入和使用再上传到真正的PyPI。因为PyPI上的版本号一旦使用就无法重复上传只能递增。4.3 上传后的验证与安装上传成功后你可以在PyPI上搜索你的项目名查看项目主页。检查README、描述、分类器等是否显示正确。在一个全新的虚拟环境中尝试安装你的包# 创建新环境以venv为例 python -m venv test_env source test_env/bin/activate # Linux/macOS # 或 test_env\Scripts\activate # Windows pip install my-awesome-tool在Python中导入并测试基本功能。5. 高级配置、持续集成与常见巨坑排查走通基本流程后要打造一个专业的、易于维护的包还需要考虑更多。5.1 动态版本管理与单一数据源在pyproject.toml中硬编码版本号version 0.1.0有个问题你的Python代码如__version__变量和文档可能也需要这个版本号多处维护容易不一致。解决方案是使用动态读取。一种常见模式是在主包目录的__init__.py中定义版本# my_awesome_tool/__init__.py __version__ 0.1.0然后在pyproject.toml中通过attr:读取这个变量[project] name my-awesome-tool dynamic [version] # 声明version是动态的 [tool.setuptools]同时创建一个setup.py或使用setuptools的扩展配置来告诉构建工具如何获取动态版本。不过更现代、更推荐的方式是使用像setuptools-scm这样的工具它可以直接从Git标签中自动派生版本号实现真正的“单一数据源”。5.2 包含与排除文件MANIFEST.in的补充虽然pyproject.toml的[tool.setuptools.package-data]可以指定包含哪些非代码文件但对于sdist源码包有时你需要更精细的控制比如包含LICENSE文件但排除.gitignore和临时文件。这时可以使用传统的MANIFEST.in文件作为补充。在项目根目录创建MANIFEST.ininclude LICENSE include README.md include CHANGELOG.md recursive-include docs *.md recursive-include my_awesome_tool/data *.json *.csv global-exclude __pycache__ global-exclude *.py[co] global-exclude .DS_Storebuild工具在构建sdist时会同时尊重pyproject.toml和MANIFEST.in。5.3 通过GitHub Actions实现自动发布每次修改都手动构建上传非常繁琐。你可以配置GitHub Actions在给Git仓库打上版本标签如v1.0.0时自动完成构建、测试、上传到PyPI的全流程。这是一个简化的.github/workflows/publish.yml示例name: Publish Python Package on: release: types: [published] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkoutv3 with: fetch-depth: 0 # 获取所有历史用于setuptools-scm如果用了 - name: Set up Python uses: actions/setup-pythonv4 with: python-version: 3.x - name: Install dependencies run: | python -m pip install --upgrade pip pip install build twine - name: Build package run: python -m build - name: Publish to PyPI env: TWINE_USERNAME: __token__ TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }} run: twine upload dist/*你需要将PyPI的API令牌存储在GitHub仓库的Settings - Secrets - Actions中命名为PYPI_API_TOKEN。这样发布流程就完全自动化了。5.4 高频踩坑点与解决方案结合网络热词中反映的常见pip安装问题作为包作者你可以从源头避免很多坑坑ModuleNotFoundError: No module named ...或Package not found根因pyproject.toml中的name与代码中import使用的包名不匹配或者[tool.setuptools.packages.find]配置错误导致核心包没有被包含进分发文件中。排查解压生成的.tar.gz或.whl文件检查里面的目录结构看你的包目录如my_awesome_tool/是否在正确位置。确保pyproject.toml中的name是用于pip install的而代码中的import语句使用的是包目录名。坑安装后运行命令行工具失败根因如果你的包提供了命令行入口需要在配置中声明。在pyproject.toml中添加[project.scripts] my-cli-command my_awesome_tool.cli:main这会在安装时在用户系统的可执行路径下创建一个名为my-cli-command的脚本指向你代码中my_awesome_tool.cli模块的main函数。坑依赖版本冲突根因在dependencies中使用了过于严格或过于宽松的版本限定。建议遵循语义化版本规范。对于你自己高度依赖其API的功能可以使用x.y.z, next.major如2.25.0, 3.0.0。对于非核心依赖使用x.y.z即可。上传前最好在一个干净环境中用pip install .测试安装看是否会引发冲突。坑包含数据文件但运行时找不到根因忘记在pyproject.toml中配置[tool.setuptools.package-data]或者路径声明错误。解决正确配置package-data并在代码中使用importlib.resources或pkgutil等标准库来安全地访问包内数据文件而不是依赖当前工作目录。坑上传失败提示“HTTPError: 403 Forbidden”根因1包名在PyPI上已被占用。上传前务必先搜索。根因2使用了错误的API令牌或令牌权限不足。确保使用TestPyPI令牌上传到测试站主站令牌上传到主站。根因3网络问题或PyPI服务暂时异常。可稍后重试。关于“pip镜像”和安装速度作为用户你可以配置镜像源加速下载。作为包作者你无法控制用户从哪里下载但你可以确保你的包文件尤其是wheel尽可能小依赖尽可能少这本身就能提升安装体验。同时在README中提示用户可以使用国内镜像也是一种体贴。

相关新闻

Unity3D RPG 入门项目(七)技能系统、Excel 配表解析、StreamingAssets 资源目录

Unity3D RPG 入门项目(七)技能系统、Excel 配表解析、StreamingAssets 资源目录

核心知识点:技能界面 BasePanel 搭建、Excel 表格第三方库解析、StreamingAssets 与 Resources 区别、技能完整 XML/Excel 配置字段、枚举分类、文件 IO 读取、按职业筛选技能、通用 Item 预制复用、项目通用 UI 开发思路一、技能界面基础搭建1 概念独立技能弹窗面板…

2026/10/12 20:07:57 阅读更多 →
电商用户沟通流程怎么优化?个人微信API打通5个触点增加复购率

电商用户沟通流程怎么优化?个人微信API打通5个触点增加复购率

今年开春接了个活儿,客户是做美妆电商的,天猫店加独立站两条腿走路。他们找我的时候甩了一个数据过来:购物车放弃率40%。意思是每10个把商品加进购物车的客户,有4个最后没付款就走了。 这个数字在美妆类目不算夸张,但…

2026/10/11 6:52:13 阅读更多 →
Deltix开放测试版:像真实用户一样测试移动应用,支持多模式、多场景及未来规划!

Deltix开放测试版:像真实用户一样测试移动应用,支持多模式、多场景及未来规划!

像真实用户一样测试你的移动应用用通俗易懂的英语描述一项任务,Deltix会在模拟器上运行该任务,并告诉你真实用户是否能够完成它。目前其处于开放测试版,支持iOS,无需信用卡即可开始免费试用。查看实际运行情况可在YouTube上观看 “…

2026/10/12 2:31:57 阅读更多 →

最新新闻

可靠性数据统计方法与R语言实战:从配套数据集到Weibull建模

可靠性数据统计方法与R语言实战:从配套数据集到Weibull建模

简介:《Statistical Methods for Reliability Data》配套数据集面向可靠性建模学习者和从业者,是这本经典著作的实操补充。包内围绕寿命分布、生存分析、故障率函数、可靠性增长、多组件系统可靠性、寿命试验设计与统计推断等核心知识点,提供…

2026/10/12 20:07:21 阅读更多 →
AI编程agent失控?用最小规格驱动工作流守住代码边界

AI编程agent失控?用最小规格驱动工作流守住代码边界

我本来是想抄作业的。Spec Kit、OpenSpec、Superpowers 这三个名字,我在搜索框里来回扫了不止一遍。原因很简单:最近一段时间的 AI 编程 agent 越来越难控制,改一个登录模块,它能顺手把我另一个文件的变量名也改了;说好…

2026/10/12 20:07:21 阅读更多 →
自建技术博客的完整实践:从静态站点生成到命令行发布

自建技术博客的完整实践:从静态站点生成到命令行发布

1. 起点:为什么要自建博客,而不是继续躺在平台里我相信每个写过一段时间技术博客的人,都会在某一天产生一个念头:我写的内容到底属于谁?这个念头在我身上盘旋了很久。平台给流量、给推荐、给了现成的排版和读者&#x…

2026/10/12 20:07:21 阅读更多 →
开放代码评审实践:从零搭建轻量级评审工具与流程

开放代码评审实践:从零搭建轻量级评审工具与流程

1. 为什么“代码评审”这件事值得单独拿出来做一套工具代码评审(Code Review)是研发流程里最容易被口号化、也最容易被敷衍的一环。几乎每个团队都声称自己在做评审,但真正落到日常,往往是三种状态:要么是“橡皮图章式…

2026/10/12 20:07:21 阅读更多 →
open-code-review:让代码评审有据可查、有果可闭环的工程实践

open-code-review:让代码评审有据可查、有果可闭环的工程实践

1. 项目概述:open-code-review 到底要解决什么代码评审这件事,但凡在团队里待过一两年的人,都经历过那种“评审2小时,改动3行”的尴尬局面。评审邮件发出去没人理,约了个会议大家对着屏幕沉默,等终于有人说…

2026/10/12 20:07:21 阅读更多 →
贷中风险预测竞赛级Python源码解析:从多表合并到LightGBM建模

贷中风险预测竞赛级Python源码解析:从多表合并到LightGBM建模

简介:面向计算机专业毕业设计、期末大作业及金融风控入门实践,这份完整项目包以贷中风险预测为核心任务,基于Python机器学习完整覆盖数据清洗、特征工程、模型训练与效果评估流程,适合需要从零构建实际项目的初中级学习者。资源共…

2026/10/12 20:06:21 阅读更多 →

日新闻

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

在数码相机、高清显示屏与现代矢量图形技术高度发达的今天,画面可以做到绝对的锐利、平滑与无瑕。然而,当一张秋日手账插画或拍立得照片过于“平整无瑕”时,往往会散发出一种冰冷生硬的“数码塑料感(Digital Plasticity&#xff0…

2026/10/12 0:00:59 阅读更多 →
活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

在现代网页与移动端设计中,横排(Horizontal Layout)早已经成为了绝对的主流。然而,当我们翻开泛黄的线装古籍、宋版木刻诗集,或是欣赏一张茶道雅集的手写便签时,那种**自上而下纵向书写、自右向左逐列铺展&…

2026/10/12 0:00:59 阅读更多 →
周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

每到周日的晚上八点到十点,很多人心里都会悄悄亮起一盏警示灯。 在心理学上,这种现象有一个专门的称谓——“周日夜晚焦虑症(Sunday Scaries)”。明天又是周一,闹钟又要重新在七点响彻卧房;脑海里仿佛有一个…

2026/10/12 0:00:59 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/12 0:16:30 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/12 0:16:43 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →