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 开发的标准。

相关推荐
小同志002 小时前
IoC 详解
java·开发语言
t***5442 小时前
如何在 Dev-C++ 中设置和使用 Clang 编译器
开发语言·c++
西门大盗2 小时前
pycharm自动进行python 测试(python test)
ide·python·pycharm
Jmayday2 小时前
Pytorch:张量的操作
人工智能·pytorch·python
石榴树下的七彩鱼2 小时前
智能抠图 API 多语言接入实战:从零到上线的 Python / Java / PHP / JS 完整教程(附避坑指南)
java·python·php·智能抠图·api接入·石榴智能·shiliuai
csbysj20202 小时前
Markdown 段落格式
开发语言
无限进步_2 小时前
C++ 继承机制完全解析:从基础原理到菱形继承问题
java·开发语言·数据结构·c++·vscode·后端·算法
leo__5203 小时前
基于时延的麦克风声源定位 - C实现
c语言·开发语言·算法
jf加菲猫3 小时前
第15章 文件和目录
开发语言·c++·qt·ui