使用Python setuptools安装后脚本

2024-04-25 07:32:54 发布

您现在位置:Python中文网/ 问答频道 /正文

是否可以将安装后Python脚本文件指定为setuptools setup.py文件的一部分,以便用户可以运行以下命令:

python setup.py install

在本地项目文件存档中,或

pip install <name>

对于PyPI项目,脚本将在标准setuptools安装完成时运行?我希望执行可以在单个Python脚本文件中编码的安装后任务(例如,向用户发送自定义的安装后消息,从不同的远程源存储库提取其他数据文件)

我遇到了this SO answer from several years ago解决了这个主题,当时的共识似乎是您需要创建一个install子命令。如果情况仍然如此,是否有人可以提供一个示例,说明如何执行此操作,以便用户无需输入第二个命令来运行脚本


Tags: installpip文件项目用户namepy命令
3条回答

注意:以下解决方案仅在安装源发行版zip或tarball,或从源代码树以可编辑模式安装时有效。从二进制轮子(.whl)安装时,它将工作


解决方案可以是在setup.py的目录中包含一个post_setup.pypost_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__':语句允许您从命令行手动启动后期安装

注意:以下解决方案仅在安装源发行版zip或tarball,或从源代码树以可编辑模式安装时有效。从二进制轮子(.whl)安装时,它将工作


此解决方案更加透明:

您将对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):
        develop.run(self)
        # PUT YOUR POST-INSTALL SCRIPT HERE or CALL A FUNCTION

class PostInstallCommand(install):
    """Post-installation for installation mode."""
    def run(self):
        install.run(self)
        # PUT YOUR POST-INSTALL SCRIPT HERE or CALL A FUNCTION

并在setup.py中的setup()函数中插入cmdclass参数:

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 PreDevelopCommand(develop):
    """Pre-installation for development mode."""
    def run(self):
        check_call("apt-get install this-package".split())
        develop.run(self)

class PreInstallCommand(install):
    """Pre-installation for installation mode."""
    def run(self):
        check_call("apt-get install this-package".split())
        install.run(self)


setup(
    ...

p.S.setuptools上没有任何预安装入口点可用。如果你想知道为什么没有,请阅读this discussion

注意:以下解决方案仅在安装源发行版zip或tarball,或从源代码树以可编辑模式安装时有效。从二进制轮子(.whl)安装时,它将工作


当安装后脚本要求已安装包依赖项时,这是唯一对我有效的策略:

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},

相关问题 更多 >