大家好,我是良许。
最近有个朋友跟我吐槽,说他写了个Python脚本,想扔到生产环境跑,结果运维那边直接给他怼回来了:"你这一堆依赖,让我装到猴年马月?"
这事儿其实挺常见的,特别是在一些管控严格的生产环境,装个第三方库比登天还难。
今天就来聊聊怎么把Python脚本连同依赖库一起打包,直接扔到Linux上就能跑。
PyInstaller:最省事的方案
PyInstaller是最主流的打包工具,能把你的脚本和所有依赖打成一个可执行文件。
先装上:
pip install pyinstaller
最简单的用法:
pyinstaller --onefile your_script.py
这个--onefile参数会把所有东西塞进一个二进制文件里。
打包完成后,在dist目录下就能找到可执行文件,直接./your_script就能跑。
但这里有个坑,PyInstaller打包出来的文件只能在相同架构的系统上运行。
你在Ubuntu上打包的,拿到CentOS上可能会出问题。
最保险的做法是在目标系统相同的环境里打包。
如果你的脚本有数据文件或配置文件,需要用--add-data参数:
pyinstaller --onefile --add-data "config.ini:." your_script.py
Nuitka:性能狂魔的选择
Nuitka不是简单打包,而是把Python代码编译成C代码,再编译成二进制。
性能比PyInstaller强不少,而且生成的文件更小。
安装:
pip install nuitka
编译命令:
python -m nuitka --onefile --standalone your_script.py
--standalone参数会把所有依赖都打包进去。
Nuitka编译速度比较慢,但生成的文件运行速度快,适合对性能有要求的场景。
Shiv:字节码打包的轻量方案
Shiv是个相对小众但很实用的工具,它把你的代码和依赖打包成一个.pyz文件,本质上是个带shebang的zip包。
先装依赖到一个目录:
pip install -t ./libs your-dependencies
然后用Shiv打包:
pip install shiv
shiv -c your_script -o your_app.pyz ./libs
生成的.pyz文件可以直接执行,前提是目标机器上有Python解释器。
这个方案的好处是打包速度快,文件小,但需要目标机器有对应版本的Python。
Docker:终极解决方案
如果你的生产环境支持容器,直接上Docker是最稳的。
写个Dockerfile:
FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "your_script.py"]
构建镜像:
docker build -t your-app .
这样环境问题彻底解决了,而且还能保证开发环境和生产环境完全一致。
静态链接Python:硬核玩家专属
如果你想要极致的独立性,可以用staticx把PyInstaller生成的文件再包一层,把所有动态库都静态链接进去:
pip install staticx
pyinstaller --onefile your_script.py
staticx dist/your_script dist/your_script_static
这样生成的文件几乎可以在任何Linux发行版上跑,不依赖系统库。
选哪个?
如果你的脚本不复杂,目标机器有Python,用Shiv最轻量。
需要完全独立运行,PyInstaller是首选。
追求性能,上Nuitka。生产环境规范,Docker一步到位。
说白了,打包这事儿没有银弹,得根据你的实际场景选。
但不管用哪种方案,都比让运维手动装一堆依赖强多了。
毕竟谁也不想因为环境问题被喷"你这代码在我机器上跑不了"。