在Python包的__init__.py中三种模块导入方式有差异吗?
假设module.py与__init__.py处于同一目录,外部代码以import package方式导入该包时,你测试时觉得结果相同是因为三者最终都能让外部通过package.module访问到目标模块,但它们在导入逻辑、灵活性上存在明显差异:
import package.module
这是绝对导入,依赖package所在目录已被添加到Python的sys.path中。它通过完整包名定位模块,写法和外部代码导入该模块的逻辑完全一致。缺点是硬编码了包名,后续若修改包名,这行代码必须同步改动,灵活性较差。from package import module
同样属于绝对导入,只是写法简化,本质和上面的方式逻辑一致,同样依赖package在sys.path中可被识别。它直接将module对象导入到当前__init__.py的命名空间,最终也会绑定到package对象的属性上。同样存在硬编码包名的问题,包名变更时需要修改代码。from . import module
这是相对导入,以当前包(即__init__.py所在的包)为基准定位模块,不需要依赖package的完整名称,也不要求包目录在sys.path中(只要该目录被当作包导入即可)。这种写法灵活性极强,即使后续包名修改,这行代码也不需要调整,是Python包内部导入模块的推荐写法,更符合包的封装设计。
总结:在你当前的测试场景下,三者的外部表现一致,但从可维护性和包的封装性角度,from . import module是最优选择。
内容的提问来源于stack exchange,提问作者pouria forghani

