我刚写了一个python脚本,我想将它发送给朋友,以便他们可以使用它。而不是仅仅向他们发送整个文本文件并教他们如何运行它(并反过来让他们访问源代码),我想知道如何将它打包成一个"程序"他们可以随时随地运行,无需访问代码本身。
更好的是,我应该寻找什么?关于如何做到这一点的说明会有所帮助,但我也想知道我究竟可以搜索什么来获得更多相关信息。
此外,这将是从unix机器到unix机器。
答案 0 :(得分:1)
Python支持可执行档案。这是一种将程序和一堆模块包装到一个文件中的方法。例如,youtube-dl
就像这样分发。
请注意"可执行文件"基本上只是一个前面有#!
行的zip文件。因此,知识渊博的人仍然可以获得源代码。
在UNIX上,可以使用Makefile
在zip
中轻松完成此操作。
但在某些平台上,这并不容易。所以我构建了一个名为build.py
的纯Python解决方案。
"""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
复制到您的项目中。然后根据下面给出的示例自定义in __name__ == '__main__'
之后的部分。
假设目录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')