使用setuptools entry_points运行命令行脚本时导入同包模块报错
问题根因
两种运行方式的Python模块搜索路径逻辑不一致:
直接执行python autostart/filea.py时,Python会自动把脚本所在的autostart/目录加入模块搜索路径,同目录下的fileb.py会被识别为顶级模块,所以导入不报错。
但通过setuptools安装生成的filea命令行入口运行时,Python的搜索路径以site-packages根目录为基准,此时from fileb import ClassName会去全局查找顶级模块fileb,不会自动搜索autostart包的内部目录,自然触发ModuleNotFoundError。
解决方案
修正导入语句(二选一即可,优先选第一种绝对导入,是Python 3官方推荐的规范写法)
- 绝对导入写法(兼容所有运行场景):
打开autostart/filea.py,把原导入语句替换为:
改完之后不管是直接跑脚本、用包模式运行还是走安装后的命令行入口,导入逻辑都能正常工作。from autostart.fileb import ClassName - 相对导入写法:
如果不想写全包名,可以用包内相对导入:
注意:用相对导入时不能直接执行from .fileb import ClassNamepython autostart/filea.py测试,要以包模块方式启动:python -m autostart.filea,否则相对导入会报错。
- 绝对导入写法(兼容所有运行场景):
检查setup.py的包配置
确认你的setup.py没有漏配包路径,否则就算导入写对了,安装时也不会把fileb.py打包进去。推荐直接用setuptools自带的find_packages()自动识别项目下的所有包,配置示例:from setuptools import setup, find_packages setup( name="your-package-name", version="0.1", # 自动识别所有Python包 packages=find_packages(), entry_points={ 'console_scripts':[ 'filea=autostart.filea:main' ] } )重新安装包验证
改完配置和代码后,在项目根目录重新执行安装命令(开发调试可以加-e参数用editable模式,改代码不用重复安装):pip install -e .安装完成后再执行
filea命令即可正常运行。
内容的提问来源于stack exchange,提问作者user3402701
相关产品推荐
相关产品推荐

