如何将所有python代码捆绑到一个zip文件中?

Dou*_*oug 23 python pypi setup.py

在分发应用程序以将所有鸡蛋组合成单个zip文件时会很方便,这样您需要分发的只是一个zip文件和一个可执行文件(一些自定义二进制文件只需启动,加载zip文件的主要功能并踢出python关闭或类似).

我已经看过一些关于在线做这个的讨论,但没有关于如何实际做到这一点的例子.

我知道你可以(如果它的zip安全)将鸡蛋转换为zip文件.

我不确定的是:

你能以某种方式将所有鸡蛋合并成一个zip文件吗?如果是这样,怎么样?

你将如何加载和运行特定鸡蛋的代码?

你如何确保该蛋中的代码可以访问所有依赖项(即zip文件中的其他蛋)?

人们会问很多这样的东西并得到答案; 使用py2exe.是的,我明白了,这是一个解决方案.这不是我在这里问的问题......

Zar*_*art 32

您可以使用常规python工具自动完成大部分工作.让我们从干净的virtualenv开始吧.

[zart@feena ~]$ mkdir ziplib-demo
[zart@feena ~]$ cd ziplib-demo
[zart@feena ziplib-demo]$ virtualenv .
New python executable in ./bin/python
Installing setuptools.............done.
Installing pip...............done.
Run Code Online (Sandbox Code Playgroud)

现在让我们安装一组将进入压缩库的软件包.诀窍是强制将它们安装到特定目录中.

(注意:不要在命令行或pip.conf/pip.ini中使用--egg选项,因为它会破坏文件布局,使其在zip中不可导入)

[zart@feena ziplib-demo]$ bin/pip install --install-option --install-lib=$PWD/unpacked waitress
Downloading/unpacking waitress
  Downloading waitress-0.8.5.tar.gz (112kB): 112kB downloaded
  Running setup.py egg_info for package waitress

Requirement already satisfied (use --upgrade to upgrade): setuptools in ./lib/python2.7/site-packages/setuptools-0.6c11-py2.7.egg (from waitress)
Installing collected packages: waitress
  Running setup.py install for waitress

    Installing waitress-serve script to /home/zart/ziplib-demo/bin
Successfully installed waitress
Cleaning up...
Run Code Online (Sandbox Code Playgroud)

更新:pip现在有-t <path>切换,它做同样的事情--install-option --install-lib=.

现在让我们将所有这些包装成一个拉链

[zart@feena ziplib-demo]$ cd unpacked
[zart@feena unpacked]$ ls
waitress  waitress-0.8.5-py2.7.egg-info
[zart@feena unpacked]$ zip -r9 ../library.zip *
  adding: waitress/ (stored 0%)
  adding: waitress/receiver.py (deflated 71%)
  adding: waitress/server.pyc (deflated 64%)
  adding: waitress/utilities.py (deflated 62%)
  adding: waitress/trigger.pyc (deflated 63%)
  adding: waitress/trigger.py (deflated 61%)
  adding: waitress/receiver.pyc (deflated 60%)
  adding: waitress/adjustments.pyc (deflated 51%)
  adding: waitress/compat.pyc (deflated 56%)
  adding: waitress/adjustments.py (deflated 60%)
  adding: waitress/server.py (deflated 68%)
  adding: waitress/channel.py (deflated 72%)
  adding: waitress/task.pyc (deflated 57%)
  adding: waitress/tests/ (stored 0%)
  adding: waitress/tests/test_regression.py (deflated 63%)
  adding: waitress/tests/test_functional.py (deflated 88%)
  adding: waitress/tests/test_parser.pyc (deflated 76%)
  adding: waitress/tests/test_trigger.pyc (deflated 73%)
  adding: waitress/tests/test_init.py (deflated 72%)
  adding: waitress/tests/test_utilities.pyc (deflated 78%)
  adding: waitress/tests/test_buffers.pyc (deflated 79%)
  adding: waitress/tests/test_trigger.py (deflated 82%)
  adding: waitress/tests/test_buffers.py (deflated 86%)
  adding: waitress/tests/test_runner.py (deflated 75%)
  adding: waitress/tests/test_init.pyc (deflated 69%)
  adding: waitress/tests/__init__.pyc (deflated 21%)
  adding: waitress/tests/support.pyc (deflated 48%)
  adding: waitress/tests/test_utilities.py (deflated 73%)
  adding: waitress/tests/test_channel.py (deflated 87%)
  adding: waitress/tests/test_task.py (deflated 87%)
  adding: waitress/tests/test_functional.pyc (deflated 82%)
  adding: waitress/tests/__init__.py (deflated 5%)
  adding: waitress/tests/test_compat.pyc (deflated 53%)
  adding: waitress/tests/test_receiver.pyc (deflated 79%)
  adding: waitress/tests/test_adjustments.py (deflated 78%)
  adding: waitress/tests/test_adjustments.pyc (deflated 74%)
  adding: waitress/tests/test_server.pyc (deflated 73%)
  adding: waitress/tests/fixtureapps/ (stored 0%)
  adding: waitress/tests/fixtureapps/filewrapper.pyc (deflated 59%)
  adding: waitress/tests/fixtureapps/getline.py (deflated 37%)
  adding: waitress/tests/fixtureapps/nocl.py (deflated 47%)
  adding: waitress/tests/fixtureapps/sleepy.pyc (deflated 44%)
  adding: waitress/tests/fixtureapps/echo.py (deflated 40%)
  adding: waitress/tests/fixtureapps/error.py (deflated 52%)
  adding: waitress/tests/fixtureapps/nocl.pyc (deflated 48%)
  adding: waitress/tests/fixtureapps/getline.pyc (deflated 32%)
  adding: waitress/tests/fixtureapps/writecb.pyc (deflated 42%)
  adding: waitress/tests/fixtureapps/toolarge.py (deflated 37%)
  adding: waitress/tests/fixtureapps/__init__.pyc (deflated 20%)
  adding: waitress/tests/fixtureapps/writecb.py (deflated 50%)
  adding: waitress/tests/fixtureapps/badcl.pyc (deflated 44%)
  adding: waitress/tests/fixtureapps/runner.pyc (deflated 58%)
  adding: waitress/tests/fixtureapps/__init__.py (stored 0%)
  adding: waitress/tests/fixtureapps/filewrapper.py (deflated 74%)
  adding: waitress/tests/fixtureapps/runner.py (deflated 41%)
  adding: waitress/tests/fixtureapps/echo.pyc (deflated 42%)
  adding: waitress/tests/fixtureapps/groundhog1.jpg (deflated 24%)
  adding: waitress/tests/fixtureapps/error.pyc (deflated 48%)
  adding: waitress/tests/fixtureapps/sleepy.py (deflated 42%)
  adding: waitress/tests/fixtureapps/toolarge.pyc (deflated 43%)
  adding: waitress/tests/fixtureapps/badcl.py (deflated 45%)
  adding: waitress/tests/support.py (deflated 52%)
  adding: waitress/tests/test_task.pyc (deflated 78%)
  adding: waitress/tests/test_channel.pyc (deflated 78%)
  adding: waitress/tests/test_regression.pyc (deflated 68%)
  adding: waitress/tests/test_parser.py (deflated 80%)
  adding: waitress/tests/test_server.py (deflated 78%)
  adding: waitress/tests/test_receiver.py (deflated 87%)
  adding: waitress/tests/test_compat.py (deflated 51%)
  adding: waitress/tests/test_runner.pyc (deflated 72%)
  adding: waitress/__init__.pyc (deflated 50%)
  adding: waitress/channel.pyc (deflated 58%)
  adding: waitress/runner.pyc (deflated 54%)
  adding: waitress/buffers.py (deflated 74%)
  adding: waitress/__init__.py (deflated 61%)
  adding: waitress/runner.py (deflated 58%)
  adding: waitress/parser.py (deflated 69%)
  adding: waitress/compat.py (deflated 69%)
  adding: waitress/buffers.pyc (deflated 69%)
  adding: waitress/utilities.pyc (deflated 60%)
  adding: waitress/parser.pyc (deflated 53%)
  adding: waitress/task.py (deflated 72%)
  adding: waitress-0.8.5-py2.7.egg-info/ (stored 0%)
  adding: waitress-0.8.5-py2.7.egg-info/dependency_links.txt (stored 0%)
  adding: waitress-0.8.5-py2.7.egg-info/installed-files.txt (deflated 83%)
  adding: waitress-0.8.5-py2.7.egg-info/top_level.txt (stored 0%)
  adding: waitress-0.8.5-py2.7.egg-info/PKG-INFO (deflated 65%)
  adding: waitress-0.8.5-py2.7.egg-info/not-zip-safe (stored 0%)
  adding: waitress-0.8.5-py2.7.egg-info/SOURCES.txt (deflated 71%)
  adding: waitress-0.8.5-py2.7.egg-info/entry_points.txt (deflated 33%)
  adding: waitress-0.8.5-py2.7.egg-info/requires.txt (deflated 5%)
[zart@feena unpacked]$ cd ..
Run Code Online (Sandbox Code Playgroud)

请注意,这些文件应位于zip顶部,您不能只是 zip -r9 library.zip unpacked

检查结果:

[zart@feena ziplib-demo]$ PYTHONPATH=library.zip python
Python 2.7.1 (r271:86832, Apr 12 2011, 16:15:16)
[GCC 4.6.0 20110331 (Red Hat 4.6.0-2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import waitress
>>> waitress
<module 'waitress' from '/home/zart/ziplib-demo/library.zip/waitress/__init__.pyc'>
>>>
>>> from wsgiref.simple_server import demo_app
>>> waitress.serve(demo_app)
serving on http://0.0.0.0:8080
^C>>>
Run Code Online (Sandbox Code Playgroud)

更新:从python 3.5开始,还有zipapp模块可以帮助将整个包捆绑到.pyz文件中.对于更复杂的需求,pyinstaller,py2exepy2app可能更适合该法案.


Flu*_*lux 12

您可以使用标准库中的zipapp模块来创建可执行的 Python zip 存档。它从 Python 3.5 开始可用。

创建包的一种方法是添加一个名为 的顶级文件__main__.py,该文件将是执行 zip 可执行存档时 Python 运行的脚本。

假设你的目录结构现在是这样的:

??? myapp
    ??? __main__.py
    ??? myprog1.py
    ??? myprog2.py
Run Code Online (Sandbox Code Playgroud)

如果您的代码具有外部依赖项(例如在名为 的文件中列出requirements.txt),请使用以下命令将它们安装到目录中:

pip3 install -r requirements.txt --target myapp/
Run Code Online (Sandbox Code Playgroud)

注意 1:这将myapp/使用外部依赖项填充目录。

注意 2:Debian/Ubuntu 用户可能需要使用--system选项pip3,因为 Debian/Ubuntu 版本的 pip 似乎--user默认使用。

然后,使用以下命令创建 zip 可执行存档:

python3 -m zipapp myapp/
Run Code Online (Sandbox Code Playgroud)

这将创建一个名为 的 zip 可执行存档myapp.pyz,您可以通过运行来执行它:

python3 myapp.pyz
Run Code Online (Sandbox Code Playgroud)

当 zip 可执行存档被执行时,它__main__.py就是运行。

如果除了 Python 脚本之外,还需要包含 Python 脚本使用的其他数据文件(例如文本文件、PNG 图像等),请参阅:python:可执行的 zip 文件可以包含数据文件吗?


Mat*_*att 9

Python将执行zip文件,就好像它们是单个脚本一样,如果它们在顶层包含__main __.py [c]文件.然后,包导入也将检查__main__正在执行的zip内部.

因此,创建您的setup.py(py_modules = ['__main__']这里很重要,同时指定所有包和其他模块).

然后运行python setup.py bdist --format zip以创建zip文件.现在,如果您希望它可执行,您可以执行以下操作.此时,您可以像执行任何其他python脚本一样执行生成的zip文件.

Linux/Mac用户阅读本文以提高便利性的另一个步骤(尽管可能不是您提到py2exe的情况)

echo '#!/usr/bin/env python' > my_executable_zip
cat output_of_setup_py_bdist.zip >> my_executable_zip
chmod +x my_executable_zip
Run Code Online (Sandbox Code Playgroud)

这只是一个#!行到zip文件,这样当从shell运行时,您不需要指定解释器.此时你可以像系统中的任何其他二进制文件一样执行它,虽然它是一个充满python的zip文件.我通常创建一个makefile来运行setup.py然后执行此转换.