使用 Python setuptools 的安装后脚本

2024-12-27 08:47:00
admin
原创
149
摘要:问题描述:是否可以将安装后 Python 脚本文件指定为 setuptools setup.py 文件的一部分,以便用户可以运行以下命令:python setup.py install 在本地项目文件存档中,或pip install <name> 对于 PyPI 项目,脚本将在标准 setupto...

问题描述:

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

python setup.py install

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

pip install <name>

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

几年前我偶然发现了这个 SO 答案,它解决了这个主题,听起来当时的共识是您需要创建一个 install 子命令。如果情况仍然如此,是否有人可以提供一个如何执行此操作的示例,以便用户无需输入第二个命令来运行脚本?


解决方案 1:

注意:以下解决方案仅在安装源分发 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

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

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(
    ...

PS:setuptools 上没有任何可用的预安装入口点。如果您想知道为什么没有,请阅读此讨论。

解决方案 2:

注意:以下解决方案仅在安装源分发 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},

解决方案 3:

注意:以下解决方案仅在安装源分发 zip 或 tarball 时有效,或者在可编辑模式下从源树安装时有效。从二进制轮安装时无效.whl( )


一种解决方案可能是post_setup.pysetup.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__':语句允许您从命令行手动启动后安装。

解决方案 4:

结合@Apalala、@Zulu 和@mertyildiran 的答案;这在 Python 3.5 环境中对我有用:

import atexit
import os
import sys
from setuptools import setup
from setuptools.command.install import install

class CustomInstall(install):
    def run(self):
        def _post_install():
            def find_module_path():
                for p in sys.path:
                    if os.path.isdir(p) and my_name in os.listdir(p):
                        return os.path.join(p, my_name)
            install_path = find_module_path()

            # Add your post install code here

        atexit.register(_post_install)
        install.run(self)

setup(
    cmdclass={'install': CustomInstall},
...

这也使您能够访问 中的包的安装路径install_path,以便进行一些 shell 工作。

解决方案 5:

我认为执行后安装并满足要求的最简单方法是修饰对以下内容的调用setup(...)

from setup tools import setup


def _post_install(setup):
    def _post_actions():
        do_things()
    _post_actions()
    return setup

setup = _post_install(
    setup(
        name='NAME',
        install_requires=['...
    )
)

这将setup()在声明时运行setup。完成需求安装后,它将运行_post_install()函数,该函数将运行内部函数_post_actions()

解决方案 6:

如果使用 atexit,则无需创建新的 cmdclass。您只需在 setup() 调用之前创建 atexit 寄存器即可。它的作用相同。

此外,如果您需要先安装依赖项,则这不适用于pip install,因为您的 atexit 处理程序将在 pip 将包移动到位之前被调用。

解决方案 7:

我无法通过任何提出的建议解决问题,所以这是对我有帮助的。

您可以在安装后立即调用想要运行的函数,如下setup()所示setup.py

from setuptools import setup

def _post_install():
    <your code>

setup(...)

_post_install()
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用