Skip to content
0

Python项目部署

使用embeddable版本

Python的embeddable版本是一种轻量级的Python环境,它被设计为可以嵌入到其他应用程序中。这种版本的Python环境通常用于分发Python应用程序,因为它不包含文档、测试套件、工具(如IDLE)和Tkinter等。

此部署方式适用于文件较多的项目,比如Django服务。

  1. 下载对应 embeddable python 版本,下面以3.10版本为例,下载进入到解压后的文件夹内。
  2. 安装 pip 。访问网站,将里面的内容全部复制粘贴到一个py文件中,如 get-pip.py 。使用当前环境目录下的 python 解释器运行 get-pip.py 文件:如果系统安装了 python 并设置了环境变量,注意不要丢掉前面的.\,否则可能会安装到系统的 python 环境中。
powershell
.\python.exe get-pip.py

检查下是否安装成功:

powershell
.\python.exe -m pip -V

安装成功后可看到一个 Scripts 文件夹,里面就是 pip 的可执行文件。

  1. 编辑 python310._pth 文件(如果下载的是3.12版本,那就是 python312._pth 文件)

取消下面这行代码的注释

import site
  1. 使用 pip 安装自己工程的三方库。比如安装 requests:
powershell
.\python.exe -m pip install requests
# 或者进入到Scripts文件夹内
.\pip.exe install requests

会看到一个 Lib\site-packages 文件夹,里面就是三方库文件。

  1. 至此,这个文件夹就是项目的 python 运行环境了。你可以将此文件夹重命令为 venv 等,然后放到你的工程目录内,搞一个bat脚本,这样别人就能直接双击 bat 脚本启动你的工程了。

下面是一个运行 Django 的 bat 示例:( venv、 manage.py、 bat 脚本在同一目录下)

bat
@echo off
%~dp0venv/python.exe manage.py runserver 0.0.0.0:8000

%~dp0表示当前执行 bat 脚本的路径

注意

  1. 在使用 DevOps 工具等进行流水线构建时,注意不要忽略了运行环境内的 python310.zip,比如使用7z打包忽略掉了所有的zip文件。
  2. 一旦你移动或重命名这个环境目录,那么直接执行 Scripts 里面的 exe 就会失败,因为通常这些 exe 调用的 python 解释器采用的是固定路径,移动或重命名就找不到固定路径下 python.exe 文件了。可以使用模块的方式来运行:.\python.exe -m pip -V
  3. 如果需要保护源码,可以将工程内的所有 py 文件编译成 pyc 或 pyd 文件。

生成可执行文件

对于单个脚本文件的情况,生成可执行文件则更加简单。目前将py文件生成可执行文件的主流工具是nuitka和pyinstaller。

nuitka

原理是根据py文件生成C代码,再将C代码编译为exe文件,所以使用此工具需要安装C编译器。

shell
pip install nuitka  # 安装nuitka

python -m nuitka --onefile script.py

--standalone--onefile的区别:

  • standalone将程序及其所有依赖项打包成一个独立的文件夹,生成的文件夹中包含可执行文件和所有必要的依赖文件。
  • onefile将程序及其所有依赖项打包成一个单独的可执行文件。运行时,该文件会自动解压到临时目录中,然后执行,通常执行完之后会自动删除此临时目录。 测试文件func.py
python
import os

print(__file__)
print(os.getcwd())

下面是使用standalone生成的结果(func.dist文件夹下): onefile只是把standalone生成的文件夹打包成一个exe文件了,运行时会解压到临时目录运行。所以在使用onefile时,需要注意__file__是临时目录下的func.py路径。

注意

确保打包的文件路径不存在中文,虽然Nuitka会处理中文路径,但也可能会在编译时异常。

nuitak还能很方便的生成pyd文件:

python -m nuitka --module some_module.py

在windows平台下,将会生成类似some_module.cp310-win_amd64.pyd的pyd文件,其它py程序直接导入模块名some_module即可。注意:

  1. 编译生成的模块名不能修改。
  2. 扩展模块不能包含其它扩展模块。
  3. 生成的扩展模块只能用于相同版本的CPython。

pyinstaller

原理是将py文件及其依赖项打包到一个独立的可执行文件或文件夹中,并嵌入Python解释器,在运行时动态解压和加载资源,用解释器运行脚本文件。

shell
pip install pyinstaller  # 安装pyinstaller

pyinstaller -F script.py
常用参数描述
-F--onefile,类似nutika的onefile
-D--onedir,类似nutika的standalone
-w使用窗口,无控制台
-c使用控制台,无窗口(默认)

总结

  1. 打包项目最简单的方式是使用embeddable版本。
  2. 打包单个脚本文件使用nuitka或pyinstaller更方便。
  3. 打包后的exe执行时__file__会有所不同,应该使用os.path.getcwd()等方法。