如何从多个脚本构建单个python文件?

xor*_*yst 31 python

我有一个简单的python脚本,它导入我编写的各种其他模块(等等).由于我的环境,我的PYTHONPATH很长.我也在使用Python 2.4.

我需要做的是以某种方式打包我的脚本和所有不属于标准python的依赖项,以便我可以将单个文件通过电子邮件发送到我想要执行它的另一个系统.我知道python的目标版本是相同的,但它在linux上,我在Windows上.否则我只使用py2exe.

理想情况下,我想发送一个.py文件以某种方式嵌入所有必需的模块,但我决定自动构建一个zip,我只需解压缩,所需的模块都在一个目录中.

我已经看过各种包装解决方案了,但我似乎无法找到合适的方法.我错过了什么吗?

[编辑]我似乎很不清楚我在追求什么.我基本上在寻找像py2exe这样的东西,它会从给定的python脚本生成一个文件(或2个文件),自动包含所有导入的模块.

例如,如果我有以下两个文件:

[\foo\module.py]
def example():
    print "Hello"

[\bar\program.py]
import module
module.example()
Run Code Online (Sandbox Code Playgroud)

我跑:

cd \bar
set PYTHONPATH=\foo
program.py
Run Code Online (Sandbox Code Playgroud)

然后它会工作.我想要的是能够说:

magic program.py
Run Code Online (Sandbox Code Playgroud)

并最终得到一个文件,或者可能是一个文件和一个zip,然后我可以复制到linux并运行.我不想在目标linux系统上安装我的模块.

Gri*_*ave 35

我觉得这很有用:

http://blog.ablepear.com/2012/10/bundling-python-files-into-stand-alone.html

简而言之,您可以.zip您的模块并__main__.py在其中包含一个文件,这将使您能够像这样运行它:

python3 app.zip
Run Code Online (Sandbox Code Playgroud)

由于我的应用程序很小,我从主脚本链接到__main__.py.

附录:

您还可以通过在文件顶部添加一行来使zip在类UNIX系统上自行执行.这对于使用Python3的脚本可能很重要.

echo '#!/usr/bin/env python3' | cat - app.zip > app
chmod a+x app
Run Code Online (Sandbox Code Playgroud)

现在可以在不指定python的情况下执行

./app
Run Code Online (Sandbox Code Playgroud)

  • 也适用于我们的旧版 2.7 脚本。哇!遗憾的是,这一点没有被更多人所知。 (2认同)
  • 我刚刚用 Python 3.11 尝试过这个。出色的! (2认同)

Mar*_*rek 8

使用stickytape模块

stickytape scripts/blah --add-python-path . > /tmp/blah-standalone
Run Code Online (Sandbox Code Playgroud)

  • 我期望我的 Python 脚本有一个可读的串联,但对我来说,它生成了充满特殊粘性胶带调用的不可读代码。 (2认同)
  • @CGFoX 感谢您发现这一点,我更新了响应文本以反映这一点,以便为寻找人类可读输出的人们节省时间。 (2认同)

Daa*_*chi 8

您可以尝试将脚本转换为可执行文件.首先,使用:

pip install pyinstaller

安装后类型(确保您在感兴趣的文件目录中):

pyinstaller --onefile --windowed filename.py

这将创建包含所有必需模块的脚本的可执行版本.然后,您可以将此可执行文件传输(复制并粘贴)到要运行脚本的PC或计算机上.

我希望这有帮助.


Mar*_*cin 5

您应该创建一个鸡蛋文件。这是python文件的档案。

请参阅以下问题以获取指导:如何创建Python egg文件

更新:考虑2019年的车轮


xor*_*yst 1

我提出了一个涉及 modulefinder、编译器和 zip 函数的解决方案,效果很好。不幸的是,我无法在此处粘贴工作程序,因为它与其他不相关的代码混合在一起,但这里有一些片段:

zipfile = ZipFile(os.path.join(dest_dir, zip_name), 'w', ZIP_DEFLATED)
sys.path.insert(0, '.')
finder = ModuleFinder()
finder.run_script(source_name)

for name, mod in finder.modules.iteritems():
    filename = mod.__file__
    if filename is None:
        continue
    if "python" in filename.lower():
        continue

    subprocess.call('"%s" -OO -m py_compile "%s"' % (python_exe, filename))

    zipfile.write(filename, dest_path)
Run Code Online (Sandbox Code Playgroud)