pyhon相对导入

python导包问题

同级目录下的模块导入不进来

  • 在如下文件moduleB项目下直接import moduleA是会报错的,提示找不到该模块,但是可以看到moduleA和moduleB在一个项目文件夹下:


因为imiport模块的路径根据sys.path系统环境目录来导入的,而系统环境目录没有module的地址

之所以pycharm下不报错是因为,pycharm自动将路径添加到了环境目录,可以通过print(sys.path)打印看到有那些路径;可以看到pycharm是默认添加了路径:

脱离 PyCharm,直接用命令行运行,大概率会报错
正规开发里,这么导入不标准、不推荐、非常不规范

  • 所以你认为你想到了方法,将路径添加到sys.path下,那么代码就是sys.path.append(str(Path('./pkg/subpkg1').absolute()))但是这样代码管理会什么复杂混乱,哪天更改了文件名,路径就不对了,或者文件路径改变!!!
  • 所以我们采用相对导入

相对导入

点表示当前路径,两个点表示上级路径,相对导入必须以from开头,注意上级目录不要再加斜杠或反斜杠

python 复制代码
from . import modulA
from ..subPkg2 import moduleX

绝对导入(import xxx)才去 sys.path 里找模块;相对导入的逻辑不是sys.path,而是模块下的__package__(这是一个运行时变量,在不同环境中执行值不一样)中去寻找,然而当一个文件作为最开始的文件开始执行的脚本,他的__package__会被设置为none;就像主程序的__name__会被设置为__main__一样。

可以通过print(package )打印当前的package里有什么。
在启动文件下打印会打印none,但是在调用其他包里的打印__package__函数就不是空的

moduleA里的printpackage函数是我自己编写的打印__package__的函数

所以如果你想使用相对导入,可以先创建一个文件,将需要的文件相对导入写到这个文件里,然后再通过主文件绝对导入调用该文件实现

既然from a.b import c可以使用,为什么还要相对引入?

相对导入 = 给 "包内部" 自己人用的,为了【包可移动、不改名、不乱套】。

  1. 绝对导入的致命缺点:包不能挪位置
    假设你有个包叫 my_package,里面文件互相导入:
    my_package/
    a.py
    b.py

b.py 用绝对导入:

python 复制代码
from my_package import a

看上去没问题。

但万一:

包改名了 → 变成 new_package

包挪到更深的目录 → 变成 project.lib.my_package

结果:所有导入全部失效!要改几百行代码!

  1. 相对导入的无敌优势:包随便挪,永远不坏
    b.py 用相对导入:
python 复制代码
from . import a  # 就找我隔壁的 a 文件

不管你:

把包改名

把包挪到任何目录

把包发给别人用

里面的代码一行都不用改!永远正常运行。

这就是相对导入的核心价值。

  1. 正规项目为什么一定要用相对导入?

因为正规项目都是做成 "可移动的包"。

你写的不是一堆散文件,而是一个独立模块。独立模块必须做到:不依赖外部路径、不依赖项目名、随便移动都不坏。

只有相对导入能做到。

  1. 最直观的对比

绝对导入(from my_package.a import x)

依赖包名

包一改名字 → 全炸

适合:顶层入口文件、外部调用包

相对导入(from .a import x)

不依赖包名

只看当前目录

随便移动、改名都没事

适合:包内部文件互相导入

  1. 官方规范就是这么规定的

Python 官方规范:

包内部互相导入 → 必须用相对导入(带点)

外部使用包 → 用绝对导入

终极总结(背会这 2 句)

绝对导入:从外面找里面,依赖路径和包名。

相对导入:自己人找自己人,不依赖路径、随便移动都不坏。

所以:包内部文件互相导入,必须用相对导入!这才是专业 Python 开发的标准。

相关推荐
郝学胜-神的一滴16 小时前
Qt 入门 01-01:从零基础到商业级客户端实战
开发语言·c++·qt·程序人生·软件构建
测试员周周16 小时前
【Appium 系列】第06节-页面对象实现 — LoginPage 实战
开发语言·前端·人工智能·python·功能测试·appium·测试用例
摇滚侠16 小时前
@Autowired 和 @Resource 的区别
java·开发语言
2301_7838486516 小时前
优化文本分类中堆叠模型的网格搜索性能:避免训练卡顿的实战指南
jvm·数据库·python
Wy_编程16 小时前
go语言中的结构体
开发语言·后端·golang
SeaTunnel16 小时前
(八)收官篇 | 数据平台最后一公里:数据集成开发设计与上线治理实战
java·大数据·开发语言·白鲸开源
CLX050517 小时前
如何安装Oracle 12c Cloud Control_OMS服务端组件与Agent部署
jvm·数据库·python
大卡片17 小时前
C++的基础知识点
开发语言·c++
郑同学的笔记18 小时前
【Qt教程29】Qt5和Qt6版本对比
开发语言·qt
基德爆肝c语言18 小时前
Qt 主窗口全家桶:菜单栏、工具栏、状态栏与对话框完全指南
开发语言·qt