是否可以将安装后的Python脚本文件指定为setuptools setup.py文件的一部分,以便用户可以运行该命令:
python setup.py install
在本地项目文件存档,或
pip install
对于PyPI项目,脚本将在标准setuptools安装完成后运行?我希望执行可以在单个Python脚本文件中编码的安装后任务(例如,向用户提供自定义安装后消息,从其他远程源存储库中提取其他数据文件).
几年前我遇到了这个回答这个主题的答案,听起来好像当时的共识是你需要创建一个install子命令.如果仍然如此,那么有人可以提供一个如何执行此操作的示例,以便用户无需输入第二个命令来运行脚本吗?
当安装后脚本要求已经安装了软件包依赖项时,这是唯一对我有用的策略:
import atexit from setuptools.command.install import install def _post_install(): print('POST INSTALL') class new_install(install): def __init__(self, *args, **kwargs): super(new_install, self).__init__(*args, **kwargs) atexit.register(_post_install) setuptools.setup( cmdclass={'install': new_install},
一个解决方案可能是包含一个post_setup.py
in setup.py
目录.post_setup.py
将包含一个执行安装后的功能,setup.py
只会在适当的时候导入并启动它.
在setup.py
:
from distutils.core import setup from distutils.command.install_data import install_data try: from post_setup import main as post_install except ImportError: post_install = lambda: None class my_install(install_data): def run(self): install_data.run(self) post_install() if __name__ == '__main__': setup( ... cmdclass={'install_data': my_install}, ... )
在post_setup.py
:
def main(): """Do here your post-install""" pass if __name__ == '__main__': main()
通过setup.py
从其目录启动的共同想法,您将能够导入post_setup.py
其他将启动空函数.
在post_setup.py
,该if __name__ == '__main__':
语句允许您从命令行手动启动安装后.
这个解决方案更透明:
您将对setup.py进行一些添加,并且不需要额外的文件.
您还需要考虑两种不同的后期安装; 一个用于开发/可编辑模式,另一个用于安装模式.
将包含安装后脚本的这两个类添加到setup.py:
from setuptools import setup from setuptools.command.develop import develop from setuptools.command.install import install class PostDevelopCommand(develop): """Post-installation for development mode.""" def run(self): # PUT YOUR POST-INSTALL SCRIPT HERE or CALL A FUNCTION develop.run(self) class PostInstallCommand(install): """Post-installation for installation mode.""" def run(self): # PUT YOUR POST-INSTALL SCRIPT HERE or CALL A FUNCTION install.run(self)
并在setup.py中插入cmdclass
函数的参数:setup()
setup( ... cmdclass={ 'develop': PostDevelopCommand, 'install': PostInstallCommand, }, ... )
您甚至可以在安装后调用shell命令,如下所示:
from setuptools import setup from setuptools.command.develop import develop from setuptools.command.install import install from subprocess import check_call class PostDevelopCommand(develop): """Post-installation for development mode.""" def run(self): check_call("apt-get install this-package".split()) develop.run(self) class PostInstallCommand(install): """Post-installation for installation mode.""" def run(self): check_call("apt-get install this-package".split()) install.run(self) setup( ...
PS在setuptools上没有任何预先安装的入口点.如果您想知道为什么没有,请阅读此讨论.