Python 运维(三):使用 zipapp 将 Python 程序打包成单个可执行文件

在这里插入图片描述

大家好,我是水滴~~

在 Python 开发中,我们经常需要将应用程序打包成可执行文件,以便在不具备 Python 环境的计算机上运行。Python 提供了多种打包工具,其中之一就是 zipappzipapp 可以将 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 APIzipapp 模块还提供了 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 timedef greet(name):print(f"Hello, {name}!")time.sleep(2)print("再见~")time.sleep(1)

myscript.py代码内容:

from mymodule import greetdef 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应用程序。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/418372.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

FreeMarker 集合遍历

freemarker list (长度,遍历,下标,嵌套,排序) 1. freemarker获取list的size &#xff1a; Java ArrayList<String> list new ArrayList<String>(); Freemaker ${list?size} 2. list的遍历&#xff1a; <#list animals as being> <tr> <td>${be…

java 返回文件的二进制字符串给前端

RequestMapping(value "/fileToStream", method RequestMethod.GET)ApiOperation("将文件转成流传给前端")public WebResponse fileToStream(HttpServletResponse response, HttpServletRequest request){ // // 自动判断下载文件类型 // response.set…

【BZOJ-3033】太鼓达人 欧拉图 + 暴搜

3033: 太鼓达人 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 204 Solved: 154[Submit][Status][Discuss]Description 七夕祭上&#xff0c;Vani牵着cl的手&#xff0c;在明亮的灯光和欢乐的气氛中愉快地穿行。这时&#xff0c;在前面忽然出现了一台太鼓达人机台&#xff…

ubuntu创建、删除文件及文件夹,强制清空回收站方法

mkdir 目录名 > 创建一个目录 rmdir 空目录名 > 删除一个空目录 rm 文件名 文件名 > 删除一个文件或多个文件 rm –rf 非空目录名 > 删除一个非空目录下的一切 touch 文件名 > 创建一个空文件 重命名文件&#xff08;夹&#xff09; / 移…

前端学习(1987)vue之电商管理系统电商系统之通过路由加载商品列表

目录结构 router.js import Vue from vue import Router from vue-router import Login from ./components/Login.vue import Home from ./components/Home.vue import Welcome from ./components/Welcome.vue import Users from ./components/user/Users.vue import Right fr…

unity, 同步物体坐标一定要在LateUpdate中进行

设a为主动物体&#xff0c;b为跟随物体。 如果a,b都在同一个Update里更新坐标&#xff0c;那么两者自然是同步的。 如果a在a.Update里更新位置&#xff0c;而b在b.Update里将自己的位置更新为与a相同&#xff0c;那就会有误差。 而且即使a的运动非常缓慢平滑&#xff0c;b也会出…

前端学习(1988)vue之电商管理系统电商系统之获取商品列表

目录结构 router.js import Vue from vue import Router from vue-router import Login from ./components/Login.vue import Home from ./components/Home.vue import Welcome from ./components/Welcome.vue import Users from ./components/user/Users.vue import Right fr…

为什么objc_msgSend必须用汇编实现

译者前言 总是看到有人说用汇编实现objc_msgSend是为了速度快&#xff0c;当然这个不可否认。但是难道没有别的原因&#xff1f;于是就看到了这篇文章&#xff0c;遂翻译之&#xff01;。 我自己的理解就是&#xff0c;用汇编实现&#xff0c;是为了应对不同的“Calling conven…

前端学习(1989)vue之电商管理系统电商系统之渲染商品列表数据

目录结构 router.js import Vue from vue import Router from vue-router import Login from ./components/Login.vue import Home from ./components/Home.vue import Welcome from ./components/Welcome.vue import Users from ./components/user/Users.vue import Right fr…

前端学习(1990)vue之电商管理系统电商系统之自定义时间过滤器

目录结构 router.js import Vue from vue import Router from vue-router import Login from ./components/Login.vue import Home from ./components/Home.vue import Welcome from ./components/Welcome.vue import Users from ./components/user/Users.vue import Right fr…

【开源】.net 分布式架构之监控平台

开源地址: http://git.oschina.net/chejiangyi/Dyd.BaseService.Monitor .net 简单监控平台&#xff0c;用于集群的性能监控,应用耗时监控管理&#xff0c;统一日志管理等多维度的性能监控分析。集群的性能监控:&#xff08;需要服务器部署监控节点&#xff09; 1. 目前仅支持w…

hashmap有关问题与计算

1.HashMap的存储方式是数组加链表&#xff0c;主干是一个Entry数组。Entry是HashMap的基本组成单元&#xff0c;每一个Entry包含一个key-value键值对&#xff1b;当不同的key经过hash计算得出的index值相同时&#xff0c;就需要在数组里添加一个链表来存储index相同的元素&…

前端学习(1991)vue之电商管理系统电商系统之实现商品的分页功能

目录结构 router.js import Vue from vue import Router from vue-router import Login from ./components/Login.vue import Home from ./components/Home.vue import Welcome from ./components/Welcome.vue import Users from ./components/user/Users.vue import Right fr…

java httpclient发送json 请求 ,go服务端接收

/***java客户端发送http请求*/package com.xx.httptest;/*** Created by yq on 16/6/27.*/import java.io.IOException; import java.net.URLEncoder; import org.apache.commons.httpclient.*; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.co…

linux 定时备份mysql数据库

首先要先搞清楚两个概念&#xff1a; ①、mysqldump&#xff0c;mysqldump是mysql的逻辑备份工具&#xff0c;它不是linux的命令&#xff0c;工作原理类似产生一些列sql语句&#xff0c;对数据库进行指定的逻辑备份。 最简洁的形式是&#xff1a;mysqldump -uuserName -ppassW…

前端学习(1992)vue之电商管理系统电商系统之实现搜索和清空

目录结构 router.js import Vue from vue import Router from vue-router import Login from ./components/Login.vue import Home from ./components/Home.vue import Welcome from ./components/Welcome.vue import Users from ./components/user/Users.vue import Right fr…

4123: 马走日,2797:最短前缀 Trie,2362:Square 能否拼接为正方形

4123: 马走日 深度优先搜索 回溯 ///马走日 int f[21][22],n,m,t; //f数组记录点有没有走过int x[10]{-2,-2,-1,1,2,2,1,-1},y[10]{-1,1,2,2,1,-1,-2,-2};//八个方向 int x1,y1,ans; void dfs(int a,int b) //搜索过程 {bool ptrue; //标记&#xff0c;判断马是否可以遍…

前端学习(1993)vue之电商管理系统电商系统之根据id删除数据

目录结构 router.js import Vue from vue import Router from vue-router import Login from ./components/Login.vue import Home from ./components/Home.vue import Welcome from ./components/Welcome.vue import Users from ./components/user/Users.vue import Right fr…