大家好,我是水滴~~
在 Python 开发中,我们经常需要将应用程序打包成可执行文件,以便在不具备 Python 环境的计算机上运行。Python 提供了多种打包工具,其中之一就是 zipapp
。zipapp
可以将 Python 应用程序及其依赖打包成一个单独的 ZIP 文件,使其能够在没有 Python 解释器的环境中执行。
本文将详细介绍 zipapp
的使用方法,并提供代码示例,希望能够帮助新手同学快速入门。
《Python入门核心技术》专栏总目录・点这里
文章目录
- 前言
- 一、两种打包方式
- 二、通过【命令行接口】打包
- 2.1 语法结构
- 2.2 代码示例一
- 2.3 代码示例二
- 三、通过【Python API】打包
- 3.1 zipapp 模块
- 3.2 代码示例
- 总结
前言
zipapp
模块是一个 Python 标准库模块,它提供了一套管理工具,用于创建包含 Python 代码的压缩文件。这些压缩文件可以直接由 Python 解释器执行,就像运行普通的 Python 脚本一样。
使用 zipapp
模块,你可以将 Python 代码和相关依赖项打包成一个自包含的压缩文件,其中包含了应用程序的所有必要组件。这样,你可以将整个应用程序作为一个单一的文件进行分发和共享,而无需用户单独安装依赖项或设置环境。
一、两种打包方式
zipapp 模块提供了两种使用方式:
-
命令行接口:你可以在命令行中直接使用
zipapp
命令来创建压缩文件。通过命令行接口,你可以指定要打包的源代码目录、输出文件的名称以及其他选项,例如入口点和依赖项等。 -
Python API:
zipapp
模块还提供了 Python API,可以在 Python 代码中直接使用相关函数来创建压缩文件。通过 Python API,你可以以编程方式控制压缩文件的创建过程,并根据需要自定义各种选项,例如入口点、依赖项、压缩级别等。
下面将详细介绍这两种打包方式。
二、通过【命令行接口】打包
2.1 语法结构
当使用 zipapp
模块的命令行接口来创建压缩文件时,你可以使用以下语法:
python -m zipapp <source> [-h, --help] [-o <output>, --output <output>] [-p <python>, --python <python>] [-m <main>, --main <main>] [-c, --compress] [--info]
让我们来逐个介绍这些参数的含义:
参数 | 含义 |
---|---|
<source> | 必需参数,指定要打包成压缩文件的源代码目录。这个目录应该包含你的Python脚本以及其他相关文件。 |
-h, --help | 显示帮助信息并退出 |
-o <output>, --output <output> | 指定输出压缩文件的名称。默认情况下,使用源代码目录的名称,并添加 .pyz 扩展名。 |
-p <interpreter>, --python <interpreter> | 指定要使用的Python解释器。可以是解释器的路径或可执行命令。例如,-p D:\Python\Python311 或 -p python 。默认情况下,使用当前正在运行的Python解释器。 |
-m <mainfn>, -main <mainfn> | 指定应用程序的主函数,默认使用 __main__.py 。mainfn 参数的形式应为 “pkg.mod:fn”,其中 “pkg.mod”是打包文件中的某个包/模块,“fn”是该模块中的一个可调用函数。 |
-c, --compress | 指定是否使用默认的压缩方法对文件进行压缩。默认情况下,文件是未经压缩的存储的。 |
--info | 显示压缩文件中的解释器信息。当你指定 --info 参数时,zipapp 将提取压缩文件中的解释器信息,并将其显示在命令行中。这对于查看压缩文件中使用的Python解释器的路径和版本非常有用。 |
2.2 代码示例一
现在,让我们看一个示例,演示如何使用命令行接口来创建压缩文件。
假设我们有以下目录结构:
myapp1
|-- myscript.py
|-- mymodule.py
mymodel.py
代码内容:
# utils.py
import time
def greet(name):
print(f"Hello, {name}!")
time.sleep(2)
print("再见~")
time.sleep(1)
myscript.py
代码内容:
from mymodule import greet
def hello():
name = input("请输入你的名字: ")
greet(name)
if __name__ == "__main__":
hello()
我们想要将 myapp1
目录打包成一个可执行的压缩文件。
使用以下命令:
python -m zipapp myapp1 -m myscript:hello -o myapp1.pyz
这将创建一个名为 myapp1.pyz
的压缩文件,其中 myscript:hello
将作为入口点(即:使用 myscript.py
模块下的 hello
函数作为入口点)。你可以直接运行该文件来执行你的Python应用程序。
2.3 代码示例二
如果模块中没有 __main__.py
文件,则 -m
参数是必须;如果有该入口文件,则无需指定了。下面将演示使用默认的__main__.py
文件表示主函数的方式。
创建一个myapp2
目录,并将myapp1
中的两个 Python 文件拷贝到 myapp2
中,最后将 myapp2
中的myscript.py
重命名为 __main__.py
myapp2
|-- __main__.py
|-- mymodule.py
下面将 myapp2
目录打包成一个可执行的压缩文件,命令如下:
python -m zipapp myapp2 -o myapp2.pyz
这将创建一个名为 myapp2.pyz
的压缩文件,并默认使用 __main__.py
文件作为入口函数(要求该文件下必须有main
函数)。你可以直接运行该文件来执行你的Python应用程序。
三、通过【Python API】打包
3.1 zipapp 模块
zipapp
模块是 Python 3.5 引入的标准库,可以通过以下方式导入:
import zipapp
zipapp 模块提供了一个函数 create_archive()
,用于创建 zipapp 文件。该函数的基本语法如下:
zipapp.create_archive(source, target, interpreter=None, main=None, compressed=False)
-
source
:要打包的源目录或源文件的路径。 -
target
:生成的zipapp
文件的路径。 -
interpreter
:可选参数,指定要用于执行zipapp
的 Python 解释器路径。 -
main
:可选参数,指定zipapp
的入口点(main 函数)路径。 -
compressed
:可选参数,指定是否压缩生成的zipapp
文件。
3.2 代码示例
我们还是使用上一节中的目录结构:
myapp1
|-- myscript.py
|-- mymodule.py
myapp2
|-- __main__.py
|-- mymodule.py
创建一个zipapp打包.py
的 Python 文件,内容如下:
import zipapp
# 打包 myapp1 目录,并指定 myscript:hello 为入口函数
zipapp.create_archive("myapp1", "myapp1.pyz", main='myscript:hello')
# 打包 myapp2 目录,默认使用 __main__.py 为入口文件
zipapp.create_archive("myapp2", "myapp2.pyz")
以上代码使用了 zipapp 模块来创建压缩文件。
-
首先,通过
import zipapp
导入了zipapp
模块。 -
第一个
zipapp.create_archive()
函数调用用于打包名为 “myapp1” 的目录,并将其保存为 “myapp1.pyz” 压缩文件。同时,使用main='myscript:hello'
参数指定了入口函数为 “myscript:hello”。这意味着在执行压缩文件时,将会调用 “myscript” 模块中的 “hello” 函数作为应用程序的入口点。 -
第二个
zipapp.create_archive()
函数调用用于打包名为 “myapp2” 的目录,并将其保存为 “myapp2.pyz” 压缩文件。这里没有指定 main 参数,因此默认使用目录中的__main__.py
文件作为入口文件,执行时会调用该文件件中的主函数。
通过以上代码,你可以创建两个压缩文件 “myapp1.pyz” 和 “myapp2.pyz”。其中 “myapp1.pyz” 使用 “myscript:hello” 函数作为入口点,而 “myapp2.pyz” 使用目录中的__main__.py
文件作为入口点。
总结
使用zipapp
模块,你可以轻松地将 Python 应用程序打包成一个独立的可执行文件,方便地在不同的环境中部署和分享。无论是通过命令行接口还是 Python API,zipapp
模块都提供了灵活的工具,使你能够创建自包含的Python应用程序。