如何编写Python import语句使文件在包内外运行均无导入错误
问题核心原因
两个报错的底层逻辑如下:
- 直接运行
pkg_file_1.py时,Python会将脚本所在的the_package目录加入模块搜索路径,上层的package_example目录不在搜索路径里,所以找不到the_package模块,触发第一个报错。 - 直接运行脚本时,当前脚本的
__name__属性为__main__,Python不会将其识别为包的一部分,相对导入会失去父包上下文,触发第二个报错;另外你之前写的from ..the_package import pkg_file_2本身也有语法错误,同目录下的同包模块相对导入只需要一个点:from . import pkg_file_2。
解决方案
方案1:兼容式导入(无需修改运行命令,最常用)
直接修改pkg_file_1.py的导入逻辑,用异常捕获适配两种场景:
# pkg_file_1.py 完整代码 try: # 作为包模块被外部调用时的导入路径 from the_package import pkg_file_2 except ImportError: # 直接运行本文件时的导入路径 import pkg_file_2 def foo_1(): print("this is the second version, foo_1") pkg_file_2.foo_2() if __name__ == "__main__": foo_1()
改完之后不管是运行main.py,还是直接运行pkg_file_1.py都不会报错。
方案2:遵循Python包运行规范,用-m参数运行
如果不想写兼容判断,可以统一用Python的模块运行方式,导入用标准相对导入:
首先修改pkg_file_1.py的导入为同包相对导入:
# pkg_file_1.py 导入部分修改 from . import pkg_file_2
运行的时候不要直接跑pkg_file_1.py,而是在package_example目录下执行命令:python -m the_package.pkg_file_1
这种方式更符合Python的包设计规范,适合工程化项目使用。
扩展场景:如果需要跨层级导入上层包内容
如果你的模块需要导入包外或者更上层的模块,可以在直接运行的分支主动添加上层目录到搜索路径:
import sys from pathlib import Path # 优先用包模式导入 try: from the_package import pkg_file_2 from the_package.utils import xxx except ImportError: # 直接运行时添加上层目录到搜索路径 sys.path.append(str(Path(__file__).parent.parent.resolve())) from the_package import pkg_file_2 from the_package.utils import xxx
内容的提问来源于stack exchange,提问作者CSStudent7782
相关产品推荐
相关产品推荐

