Python模块创建疑问:为何需用my_module.my_module.foo形式导入?
嘿,我完全懂你这种绕晕的感觉——刚接触Python包结构的时候,这种嵌套的同名文件夹确实容易让人摸不着头脑!咱们一步步拆解问题:
为什么会需要from my_module.my_module.foo import ...?
你当前的结构是这样的:
my_module/ # 外层项目根目录 ├── setup.py └── my_module/ # 真正的Python包目录 ├── __init__.py ├── foo.py └── foo2.py
- 外层的
my_module只是项目的管理目录,它本身不是Python识别的包(哪怕有__init__.py,也不是你要打包分发的核心代码)。 - 内层的
my_module才是真正的Python包,因为它包含__init__.py,是你要对外提供的模块集合。
当你在项目根目录(外层my_module)下直接运行脚本时,Python会把当前目录加入模块搜索路径。这时候,外层my_module作为一个目录被识别,你需要通过my_module.my_module才能定位到内层的包,所以才会出现这种冗长的导入路径。
怎么改成简洁的from my_module.foo import ...?
有两种常用的解决方式,看你的需求选:
1. 以开发模式安装包(推荐)
这是Python包开发的标准做法,能让你在修改代码后无需重新安装,同时拥有正常的导入路径。
在项目根目录(外层my_module)下运行:
pip install -e .
这个命令会把内层的my_module包注册到Python的site-packages目录里,之后不管你在哪个目录运行代码,都能直接用from my_module.foo import xxx,完全不需要嵌套路径。
2. 调整运行目录或手动添加路径(临时调试用)
如果你不想安装包,只是临时调试代码:
方法一:切换运行目录
退到外层my_module的上级目录,比如你的结构是parent_dir/my_module/,就进入parent_dir,然后运行你的脚本。这时候Python会把parent_dir加入搜索路径,内层的my_module作为独立包就能被直接识别,你可以用from my_module.foo import xxx。方法二:手动添加包路径
在你的脚本开头,把内层my_module的路径加入Python的搜索路径:import sys from pathlib import Path # 获取当前脚本所在目录(外层my_module),拼接内层包路径 sys.path.append(str(Path(__file__).parent / "my_module"))之后你就能直接用
from my_module.foo import xxx或者from foo import xxx(不过更推荐前者,保持包结构的清晰性)。
额外说明:这种结构的合理性
其实这种“外层项目目录+内层同名包目录”是Python包的标准结构,好处在于:
- 把项目的配置文件(setup.py、README、requirements.txt等)和核心代码分开,打包分发时只会把内层的包目录包含进去,不会混入无关文件。
- 符合PyPI包的规范,方便后续发布你的模块。
内容的提问来源于stack exchange,提问作者Stefano Frassetto

