使用setuptools安装自定义Python包后导入失败及egg格式疑问求助
MESSAGE的解决方案 你遇到的导入错误,核心和setuptools处理scripts参数的方式有关。当你用scripts=["hello.py"]时,setuptools会自动给脚本添加pkg_resources的引导代码,这个过程干扰了模块的导入路径,导致无法正确从hello包中找到MESSAGE。这里有两个可靠的解决方法:
方法1:改用entry_points替代scripts(推荐)
这是现代Python包推荐的方式,能避免setuptools修改脚本带来的潜在问题。
- 调整项目结构,把原来
hello.py的内容移到hello/main.py中:
# hello/main.py def main(): from hello import MESSAGE print(MESSAGE) if __name__ == "__main__": main()
- 修改
setup.py,替换scripts参数为entry_points:
from setuptools import setup setup( name="Hello World", version="1.0.0", description="Hello World", url="http://www.example.com", author="XX", author_email="XX@YY.ZZ", license="XXX", # 替换原来的scripts配置 entry_points={ 'console_scripts': [ 'hello=hello.main:main', ], }, packages=["hello"] )
- 重新安装:
python3 setup.py install --user
现在直接运行hello命令(而非hello.py),就能正常输出Hello, World!了。
方法2:修改原脚本的导入逻辑(临时方案)
如果你不想调整结构,可以修改hello.py,确保导入时使用绝对路径,或者显式确认包的位置:
#!/usr/bin/env python3 import sys from importlib.util import find_spec # 确保hello包在路径中 if not find_spec("hello"): # 源码目录运行时,添加当前目录到路径 sys.path.insert(0, ".") from hello import MESSAGE print(MESSAGE)
不过这个方法不如第一种优雅,长期来看还是推荐用entry_points方案。
另外,你可以先检查安装后的包是否正确:前往$HOME/.local/lib/python3.6/site-packages/Hello_World-1.0.0-py3.6.egg/hello/目录,确认__init__.py和message.py都存在,且__init__.py里确实有from .message import MESSAGE这行代码。如果文件缺失,重新运行安装命令即可。
默认情况下,python setup.py install会生成egg格式的包,这是setuptools传统的包格式。而wheel是现在官方推荐的格式,要生成或使用wheel,需要做两步:
- 先安装wheel工具:
pip install wheel --user
- 之后如果要生成wheel包,运行:
python3 setup.py bdist_wheel
生成的wheel文件会在dist/目录下。如果要直接用wheel格式安装你的包,也可以用pip命令替代setup.py:
pip install . --user
pip会自动优先构建并使用wheel格式进行安装。
内容的提问来源于stack exchange,提问作者rdanter

