仅将python脚本作为可执行文件发送

仅将python脚本作为可执行文件发送,python,python-3.x,scripting,Python,Python 3.x,Scripting,我刚刚写了一个python脚本,我想把它发送给一个朋友,这样他们就可以使用它了。我想知道如何把它打包成一个“程序”,他们可以随时运行,而不需要访问代码本身 更好的是,我应该寻找什么?关于如何做到这一点的说明将有所帮助,但我也想知道我可以搜索什么来获得更多信息 此外,这将从unix计算机传输到unix计算机。Python支持可执行归档。这是一种将一个程序和一组模块封装到单个文件中的方法。例如,youtube dl是这样分发的 请注意,“可执行文件”基本上只是一个带有#的zip文件-前面一行。所以一

我刚刚写了一个python脚本,我想把它发送给一个朋友,这样他们就可以使用它了。我想知道如何把它打包成一个“程序”,他们可以随时运行,而不需要访问代码本身

更好的是,我应该寻找什么?关于如何做到这一点的说明将有所帮助,但我也想知道我可以搜索什么来获得更多信息


此外,这将从unix计算机传输到unix计算机。

Python支持可执行归档。这是一种将一个程序和一组模块封装到单个文件中的方法。例如,
youtube dl
是这样分发的

请注意,“可执行文件”基本上只是一个带有
#的zip文件-前面一行。所以一个知识渊博的人仍然可以获得源代码

在UNIX上,使用
zip
Makefile
中轻松实现这一点。 但在某些平台上,这并不容易。因此,我构建了一个只有Python的解决方案,名为
build.py

"""Create runnable archives from program files and custom modules."""

import os
import py_compile
import tempfile
import zipfile as z


def mkarchive(name, modules, main='__main__.py',
              shebang=b'#!/usr/bin/env python3\n'):
    """Create a runnable archive.

    Arguments:
        name: Name of the archive.
        modules: Module name or iterable of module names to include.
        main: Name of the main file. Defaults to __main__.py
        shebang: Description of the interpreter to use. Defaults to Python 3.
    """
    std = '__main__.py'
    if isinstance(modules, str):
        modules = [modules]
    if main != std:
        try:
            os.remove(std)
        except OSError:
            pass
        os.link(main, std)
    # Forcibly compile __main__.py lest we use an old version!
    py_compile.compile(std)
    tmpf = tempfile.TemporaryFile()
    with z.PyZipFile(tmpf, mode='w', compression=z.ZIP_DEFLATED) as zf:
        zf.writepy(std)
        for m in modules:
            zf.writepy(m)
    if main != std:
        os.remove(std)
    tmpf.seek(0)
    archive_data = tmpf.read()
    tmpf.close()
    with open(name, 'wb') as archive:
        archive.write(shebang)
        archive.write(archive_data)
    os.chmod(name, 0o755)


if __name__ == '__main__':
    pass
这不应该在未经修改的情况下使用

build.py
复制到项目中。然后根据下面给出的示例,在uuu name uuu=='uuu main uuu'
中自定义
后面的零件

假设目录
src
包含几个Python文件,
eggs.py
ham.py
foo.py
。它还包含一个子目录
spam
,其中包含所有脚本都使用的Python模块。以下代码将创建三个可执行归档文件,
eggs
ham
foo

if __name__ == '__main__':
    from shutil import copy
    os.chdir('src')
    programs = [f for f in os.listdir('.') if f.endswith('.py')]
    for pyfile in programs:
        name = pyfile[:-3]
        mkarchive(name, 'spam', pyfile)
        copy(name, '../'+name)
        os.remove(name)
如果您只想使用单个文件:

if __name__ == '__main__':
    mkarchive('scriptname', None, 'filename.py')

Unix附带Python。如果您没有依赖项,只需使.py文件可执行,添加一个hash bang并发送它。如果您不想教他们如何运行它,您可以耐心等待他们学习。@jornsharpe打包通常没有那么简单,除非您没有依赖项,并且您知道目标机器Python版本是兼容的。更好的方法是编写一个
setup.py
文件并创建一个发行版。相关的,如果不是重复的话:@wim,可能需要更多的信息。我认为这两种方法都很酷,谢谢!关于这一点,有两个问题。整个脚本只是一个名为GradeCalculator.py的文件。在这种情况下,我需要在if name='main':下以mkarchive开头的行,还是可以省略该行?(看起来这行与子目录spam有关。在我的情况下,我没有任何额外的子目录)。我以前可能应该提到我的脚本的简单性。第二个问题是,我是否省略了“pass”(第一块代码中的最后一行)?哦,好的,我知道现在发生了什么。谢谢,这很有效。我不得不对你的代码进行一些编辑,因为我没有使用额外的模块,但除此之外,一切正常。