如何指定setup.py安装所需依赖?解决导入模块失败问题
解决setup.py中依赖导入的setup_requires无效问题
这个问题我之前也踩过坑!核心原因其实很直白:你在setup()函数调用之前就直接导入了foo,但setup_requires是在setup()执行过程中才会触发依赖安装的——这就导致代码跑到import foo时,依赖还没被安装,自然就抛出ImportError了。
下面给你几个靠谱的解决方案:
方案1:延迟导入(最推荐)
把需要依赖foo的逻辑封装成函数,只在setup()内部调用这个函数。这样setuptools会先处理setup_requires安装foo,再执行函数里的导入逻辑:
from setuptools import setup def get_version(): # 这里的导入会在setup_requires安装foo之后才执行 import foo return foo.generate_version() setup( version=get_version(), setup_requires=['foo'] )
这种方式既简洁又符合setuptools的设计逻辑,是社区最常用的解决办法。
方案2:手动触发依赖检查(适合复杂场景)
如果你的逻辑更复杂,可以用pkg_resources先检查依赖是否存在,不存在的话让setuptools先安装:
from setuptools import setup from pkg_resources import require, DistributionNotFound try: # 先尝试导入依赖 import foo except ImportError: try: # 触发setup_requires安装 require('foo') except DistributionNotFound: # 先执行一次setup来安装setup_requires setup(setup_requires=['foo']) # 安装完成后再导入 import foo setup( version=foo.generate_version() )
这种方式略显繁琐,但适合需要在setup()之前做一些额外预处理的场景。
额外建议:改用pyproject.toml(现代方案)
如果你用的是较新版本的setuptools,可以考虑遵循PEP 518规范,用pyproject.toml来声明构建依赖。这种方式能让pip在执行setup.py之前就安装好所有构建时需要的依赖,从根源上避免这类问题:
# pyproject.toml [build-system] requires = ["setuptools", "foo"] build-backend = "setuptools.build_meta"
配置好这个文件后,你在setup.py里就可以直接导入foo了,无需再纠结导入时机的问题。
内容的提问来源于stack exchange,提问作者TitanSnow
相关产品推荐
相关产品推荐

