当前位置:首页>python>Python虚拟环境下修改源码后uv重新打包那些事

Python虚拟环境下修改源码后uv重新打包那些事

  • 2026-09-09 16:21:29
Python虚拟环境下修改源码后uv重新打包那些事

关注我:ღ双识求索ღ藏器于身,待时而动。

知识就是力量,知识改变命运;科技就是生产力,AI就是即战力!

Python虚拟环境下功能修改通常是修改源代码,然后重新打包。但具体要看这个新增功能是属于哪个部分的逻辑。可能是核心逻辑 (core.py) 或主界面 (main.py)。比如想增加一个新的输出文件,很可能需要修改 core.py 中的保存逻辑,也可能要修改 main.py 增加一些设置。但无论如何,都需要修改源代码文件后重新打包,生成新的 exe。所以应该需要修改对应的源文件并重新打包。

同时注意提醒:main.py 只是 GUI 入口,实际的保存功能在 core.py 中,所以如果是要增加一个 txt 文件输出(比如除了 intersection_ssq.txt 之外再多一个),应该修改 core.py 中的 save_results 方法。然后重新打包。

具体操作流程

1. 确定要增加的功能位置

如果需要增加一个额外的 txt 文件输出,这很可能是在 核心计算结果保存 的地方。

在具体的项目里,保存结果会调用 core.py 中的 save_results 方法,目前它只生成 exeLottoSSQ/intersection_ssq.txt。

如果想同时输出另一个文件(比如统计信息、调试日志等),应该在 core.py 的 save_results 或 run() 方法中增加新的写入逻辑。

如果是 GUI 上的调整(例如增加一个按钮来选择输出路径、显示额外信息),则要修改 main.py。

  • 主要修改 core.py(文件名及额外输出)。

  • 检查 main.py 中是否有固定引用旧文件名的地方(通常没有,因为文件名动态生成并打印,无需改 GUI)。

2. 修改源码

打开对应的源文件,添加你需要的功能。

例如,在 save_results 中再写一个文件:

# 添加额外输出extra_file = os.path.join(output_dir, "extra_info.txt")withopen(extra_file, 'w', encoding='utf-8') as f:    f.write("需要保存的内容\n")

3.保存并重新打包回到项目根目录如(D:\projects\ssqLotto\RndMatch),用 uv run pyinstaller 再次打包:

uv run pyinstaller Match6ssq_onefile.spec   # 单文件版本uv run pyinstaller Match6ssq_onedir.spec    # 文件夹版本

打包完成后,新生成的 dist\Match6ssq\Match6ssq.exe(或 dist\Match6ssq.exe)就会包含所添加的功能。

注意事项

  • 修改源码后最好先在开发环境中运行测试一下(uv run python src/match6_ssq/main.py),确认功能正常再进行打包。

  • 打包前建议先清理旧的 build 和 dist(可选,但能避免残留文件干扰):

Remove-Item -Recurse -Force build, dist

修改源码后重新打包之前,建议清除以下两个文件夹,确保从干净状态构建:

  • build/PyInstaller 的临时工作目录,存放分析缓存、中间文件等。不清除可能因旧缓存导致新代码未生效或奇怪错误。

  • dist/打包的输出目录。不清除的话,旧文件可能残留,容易让你混淆新旧版本。

在项目根目录(D:\projects\ssqLotto\RndMatch)执行 PowerShell 命令:

Remove-Item -Recurse -Force build, dist

或者分别删除:

Remove-Item -Recurse -Force buildRemove-Item -Recurse -Force dist

不需要删除 .spec 文件,除非你也修改了打包配置(如新增隐藏导入、数据文件等)。.spec 文件是你的定制配方,保留它方便下次直接打包。

清理完毕后再执行:

uv run pyinstaller Match6ssq_onefile.specuv run pyinstaller Match6ssq_onedir.spec

这样生成的就是包含最新代码的干净程序了。

使用pyinstaller时 会在当前工作目录寻找指定的 .spec 文件,除非提供完整路径。所以确保终端当前目录是 .spec 所在目录,或者使用绝对路径,最好在 .spec 文件所在的文件夹内运行命令,否则 PyInstaller 会找不到文件。

但有两种做法:

  1. 先切换到 .spec 所在的目录(最省事)

cd D:\projects\ssqLottouv run pyinstaller Match6ssq_onefile.specuv run pyinstaller Match6ssq_onedir.spec
2.直接用绝对路径(不切换目录也行)
uv run pyinstaller D:\projects\ssqLotto\Match6ssq_onefile.specuv run pyinstaller D:\projects\ssqLotto\Match6ssq_onedir.spec
只要保证终端能找到那个 .spec 文件就行。建议直接 cd 到项目根目录执行,不容易出错。
如果 D:\projects\ssqLotto\RndMatch\pyproject.toml 存在,那么这个项目的根目录就是 RndMatch,如果遇到uv trampoline failed to canonicalize script path 错误,很可能是因为在 RndMatch 目录下时,虚拟环境或项目状态不完整导致的。
即使在正确的项目根目录(RndMatch)下,uv run pyinstaller --version 仍然报错 uv trampoline failed to canonicalize script path。这表明问题不在于目录,而在于 uv 本身与系统环境的一些交互问题。但我们已经添加了 PyInstaller 作为开发依赖,并且 uv sync 也通过了。那么我们可以绕过 uv run,直接使用虚拟环境中的 python 来调用 PyInstaller。这是最直接的解决方案。(这是 uv 在 Windows 上已知的一个偶发 bug,特别是当项目路径涉及不同盘符或某些特殊字符时,内部重定向会失败。但这并不影响虚拟环境本身的功能,直接用解释器执行命令是完全可靠的方法。)
这时应该使用虚拟环境的 python 解释器直接运行 PyInstaller,而不是通过 uv run。另外,用户可能还需要确认 PyInstaller 是否确实安装到了虚拟环境中。我们可以先检查 .venv\Scripts\python.exe -m PyInstaller --version 是否成功。如果失败,可能需要手动安装 PyInstaller 到虚拟环境(使用 pip,但虚拟环境可能没有 pip,如果 uv 创建的环境默认不带 pip,可以使用 uv pip install 命令)。但 uv add --dev pyinstaller 应该已经安装好了,只是 uv run 有问题。如果成功,则直接使用该解释器打包:.venv\Scripts\python.exe -m PyInstaller Match6ssq_onefile.spec。

uv run 的错误和项目配置无关,是 uv 工具本身在某些 Windows 环境下出现的路径规范化 bug。不过没关系,我们可以完全不依赖 uv run,直接使用项目虚拟环境里的 Python 解释器去执行 PyInstaller。极少数情况可能是 uv 版本 bug。此时可直接调用虚拟环境中的 Python 解释器来运行 PyInstaller(虚拟环境应该没有 pip,如果 uv 创建的环境默认不带 pip,可以使用 uv pip install 命令):

1. 确认 PyInstaller 已正确安装

首先测试能否通过虚拟环境中的 Python 调用 PyInstaller:

.venv\Scripts\python.exe -m PyInstaller --version

如果输出版本号(比如 6.20.0),说明安装成功,可以进行下一步。如果提示 No module named PyInstaller,则需要手动安装一下(虽然 uv add 已经做过,但为了保险):

.venv\Scripts\python.exe -m pip install pyinstaller

如果提示 No module named pip,说明虚拟环境没有自带 pip。这时可以使用 uv 来加装 pip:uv pip install --python .venv\Scripts\python.exe pip然后再次运行 pip install pyinstaller。


2. 直接打包(跳过 uv run)

确认 PyInstaller 可用后,在 RndMatch 目录下执行:

.venv\Scripts\python.exe -m PyInstaller Match6ssq_onefile.spec.venv\Scripts\python.exe -m PyInstaller Match6ssq_onedir.spec
这样就绕过了 uv 的脚本路径错误,打包会正常进行。

3. 清理旧文件再打包(强烈建议)

在打包前,先删除旧的构建产物:

Remove-Item -Recurse -Force build, dist
然后执行上述打包命令,确保生成的是最新版本。

以后每次打包,都可以沿用这个模式:

# 在项目根目录(RndMatch)下.venv\Scripts\python.exe -m PyInstaller your_spec_file.spec
如果觉得命令太长,可以激活虚拟环境后直接敲 pyinstaller:
.venv\Scripts\activatepyinstaller Match6ssq_onefile.spec
这样操作是不是更加丝滑,且完全不受 uv run 错误的影响。

Python代码更改了,那么Git仓库应该如何处理呢,那么就必须要了解一下.gitignore 规则的工作原理:

*.txt                 # 忽略所有 .txt 文件!*__ssq.txt           # 但是,不要忽略 *__ssq.txt 这类文件(取消忽略)!*__万能25码.txt       # 也不要忽略 *__万能25码.txt

这条规则的实际效果是:

  • 除了名称以 __ssq.txt 或 __万能25码.txt 结尾的文件,其余所有 .txt 文件都会被 Git 忽略。

  • 而被 ! 排除的这两个文件,反而会被 Git 跟踪,一旦它们发生变动,就会直接出现在 GitHub Desktop 的 “Changes” 列表里。

gitignore 的另一个模式规则:不带星号的目录名加斜杠表示忽略该目录及其所有内容。

如果想把程序输出的文件夹一起忽略,只需在 .gitignore 中添加,如:

exeLottoSSQ/

在 .gitignore 中写 exeLottoSSQ/ 就会忽略这个文件夹以及里面所有的文件和子文件夹。

为什么这样写就忽略了?

  • 末尾的斜杠 / 告诉 Git:这是一个目录。

  • Git 会递归忽略该目录下的所有内容,你不需要再写 exeLottoSSQ/* 或 exeLottoSSQ/**。

  • 如果你只写了 exeLottoSSQ(没有斜杠),它仍然会匹配文件夹,但斜杠是最明确、最推荐的写法。

和 *.txt 的区别

  • *.txt 是通配符匹配所有 .txt 文件,无论在哪个目录。

  • exeLottoSSQ/ 是固定路径匹配整个文件夹,不管里面有什么格式的文件。

日无所获,失落一日,日有所悟,欢欣鼓舞!

所谓千里之行始于足下: 不积跬步,无以至千里。不积小流,无以成江海。骐骥一跃,不能十步。驽马十驾,功在不舍。锲而舍之,朽木不折。锲而不舍,金石可镂。每天进步一点点,总会离成功更近一点吧!

欢迎交流,有任何问题欢迎留言讨论

AI已经让我们可以直通知识海洋的入口了,一起努力学习吧,解锁更多自动化数据分析技巧!

双识求索,在线充电,执着不倦,磨刀不止,藏器于身,待时而动。

数据分析可能大多数人都是从接触EXCEL开始的,非专业的程序员如果想要提高工作效率,学习一点程序代码还是相当有帮助的!

如要让枯燥的数据分析带来灵动的活力就需要借助程序代码进行自动化,使你的数据分析又快又好,助你高效制胜!

双识求索:分享自学学习笔记,点点滴滴,刨根究底!关注我,体验跑通代码的快乐和数据分析成功的喜悦!

如果没有很多很多的钱,能有很多很多的爱也很好,能够利用知识解决不少的问题也不错!

最新文章

随机文章