You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python 3中导入包内子模块后,主模块为何能访问未导入的同包子模块?

原因解析

1. Python包的模块挂载逻辑

当你导入mylib.foo时,Python会先初始化mylib这个包对象(哪怕mylib下的__init__.py是空文件)。随后mylib.foo里的import mylib.bar会触发mylib.bar模块的加载,并且会把bar模块直接绑定到mylib这个包对象的属性上。

换句话说,mylib作为一个全局可见的包容器,只要同包内任意模块加载了其他子模块,这些子模块就会成为mylib的属性。外部代码只要能访问mylib,就能直接调用这些已被加载的子模块。

2. numpy与mylib.bar的本质区别

mylib.foo里的import numpy是将numpy模块绑定到mylib.foo的局部命名空间,既不会挂载到mylib包对象上,也不会进入main.py的全局命名空间,所以main.py未显式导入时无法访问。

而import mylib.bar是将bar模块绑定到mylib包对象上,相当于给mylib这个容器新增了一个bar属性,因此main.py能通过mylib.bar直接访问。

3. 平级模块无此现象的原因

当foo.py和bar.py与main.py平级时,foo.py里的import bar会将bar加载到全局模块字典,但不会自动注入到main.py的全局命名空间。main.py要访问bar必须自己显式导入,或者通过sys.modules['bar']获取——不存在像mylib这样的父包容器来统一挂载所有加载过的同目录模块,因此不会出现包结构中的自动访问现象。

验证方式

你可以在main.py中添加print(dir(mylib)),会发现bar已经出现在mylib的属性列表中;而平级模块结构下,打印globals()不会看到bar的身影(除非自己显式导入)。


内容的提问来源于stack exchange,提问作者jopun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 07:42:44