如果zip文件在zip存档的顶部包含__main__.py
文件,则Python 2.6及更高版本能够直接执行.zip文件。我想利用此功能提供我正在开发的工具的预览版本,除了将.zip文件复制到磁盘之外,不需要用户安装任何东西。有没有标准的方法来创建这样的zip文件?我正在寻找一个适用于python 2.6和python 2.7的解决方案。
理想情况下,我想使用distutils,因为我想在正常安装时使用它。是否有规范的方法来使用(或扩展)distutils来创建这样的.zip文件?
distutils提供了一个sdist
命令,它可以创建一个几乎的源代码分发,但是会创建一个有点太深的结构。
例如,我的源代码树如下所示:
my_package/
- setup.py
- src/
- __main__.py
- module1/
- module2/
- module3/
当我python setup.py sdist
时,我最终得到一个带有以下结构的.zip文件:
my_package-0.1.zip
- my_package-0.1/
- README.txt
- PKG_INFO
- src/
- __main__.py
- module1/
- module2/
- module3/
这不可执行,因为__main__.py
不在分发的顶部。实际上我想要的是一个不包含src
的src发行版,而只包含src
下的文件。那个,或者恰恰是sdist
给我的,但是在档案的顶部有一个额外的__main__.py
。
答案 0 :(得分:4)
已更新:由于setup.cfg
是全局的,因此会影响所有命令的“install-lib”设置,这不是所需的。不幸的是(据我所知)没有办法通过命令行将选项传递给子命令,例如如果指定bdist --install-lib=/
,则会引发错误,而不是将其传递给子命令。
要在运行install-lib
时自定义install
子命令 的bdist
,您可以继承bdist_dumb
命令并设置路径在install
子命令构造/重新初始化后手动:
<强> setup.py 强>
from distutils.core import setup
from distutils.command.bdist_dumb import bdist_dumb
class custom_bdist_dumb(bdist_dumb):
def reinitialize_command(self, name, **kw):
cmd = bdist_dumb.reinitialize_command(self, name, **kw)
if name == 'install':
cmd.install_lib = '/'
return cmd
if __name__ == '__main__':
setup(
# our custom class override
cmdclass = {'bdist_dumb': custom_bdist_dumb},
name='my_package',
py_modules = ['__main__'],
packages = ['module1', 'module2'],
package_dir = {'': 'src'}
)
运行:
% python setup.py bdist --format=zip
% unzip -l dist/my_package-0.0.0.linux-x86_64.zip
Archive: dist/my_package-0.0.0.linux-x86_64.zip
Length Date Time Name
--------- ---------- ----- ----
184 2011-05-31 20:34 my_package-0.0.0.egg-info
30 2011-05-31 20:34 __main__.py
128 2011-05-31 20:34 __main__.pyc
107 2011-05-31 20:34 module1/__init__.pyc
0 2011-05-31 20:27 module1/__init__.py
107 2011-05-31 20:34 module2/__init__.pyc
0 2011-05-31 20:27 module2/__init__.py
--------- -------
556 7 files
% python dist/my_package-0.0.0.linux-x86_64.zip
my_package working.
答案 1 :(得分:1)
通过将以下sdist
文件放在.zip的根目录下,也可以使__main__.py
可执行:
import os
import sys
# add package .zip to python lookup path
__dir__ = os.path.dirname(__file__)
path = os.path.join(__dir__, 'my_package-0.1', 'src')
sys.path.insert(0, path)
import module1
module1.main()
这会将存档中的源子目录添加到sys.path
中,以便从module1
导入。
我现在无法告诉如何修补distutils sdist
命令以自动将此__main__.py
注入.zip
,但这绝对是真的。