page contents

Python 模块导入——绝对导入和相对导入

from . import xxx 和 from xxx.yyy import zzz 是 Python 模块导入的两种方式,它俩有什么区别你知道吗?让我们就来讨论一下。

attachments-2026-03-UCOAG9qH69c5ddfd22a15.pngfrom . import xxx 和 from xxx.yyy import zzz 是 Python 模块导入的两种方式,它俩有什么区别你知道吗?让我们就来讨论一下。

这两种写法的区别主要在于“导入来源”和“路径查找方式”。

  • from . import xxx:相对导入(就近原则,找当前文件夹下的)。

  • from xxx.yyy import zzz:绝对导入(绝对路径原则,从项目根目录找)。

下面详细总结它们的区别和使用场景:

  1. from . import xxx(相对导入)

这种写法中的 . 代表当前目录,.. 代表上一层目录。

1. 含义

告诉 Python:“不要去别处找,就在我这个文件所在的文件夹里找 xxx。”

2. 使用场景

场景A:导入同级模块

假设目录结构如下:

myproject/└── utils/    ├── __init__.py    ├── string_helper.py  <-- 这里面有一个函数 clean_text    └── file_helper.py

如果你在 file_helper.py 里想用 string_helper,因为它们都在 utils 文件夹下,是“邻居”关系:

# 在 file_helper.py 中from . import string_helper  # 意思:从当前文件夹导入 string_helper
string_helper.clean_text("...")

场景 B:导入包本身(常见于 __init__.py)
用于简化外部调用的路径。

# 在 utils/__init__.py 中from .string_helper import clean_text
# 外部调用时:# 以前需要:from utils.string_helper import clean_text# 现在只需:from utils import clean_text (因为 __init__.py 已经把它暴露出来了)

3.核心特点

  • 依赖上下文: 相对导入依赖于当前文件的 __name__ 属性。

    什么是 __name__ 属性?每个 Python 文件都有一个内置变量 __name__。如果你写了个文件 file_helper.py,在 main.py 里用 import file_helper。那么 file_helper.py 内部的 __name__ 就是 "file_helper"(即模块名)。如果你在终端运行 python file_helper.py。Python 会强制把你的 __name__ 设为 "__main__"。

  • 不能直接运行: 如果直接运行 python file_helper.py,Python 会认为它是主程序 (__main__),不属于任何包,此时 . 就找不到参照物,会报错 ImportError: attempted relative import with no known parent package。(意思是,直接运行该文件,Python 解释器把它当成了主程序,把它的名字强行改成了 __main__,它原来的名字 my_package.file_helper 被丢掉了。那么如果它里面使用了 "." (相对导入)导入同级目录下的其它包的话,会报错,因为它现在是主程序了,没有父包。)

  • 适用性: 只能在包内部使用,用于包内模块之间的互相引用。

  1. from xxx.yyy import zzz(绝对导入)

这种写法类似于文件系统中的绝对路径。

1. 含义

告诉 Python:“从 sys.path 搜索路径列表中,找到名为 xxx 的顶层包,然后进入它的 yyy 子模块,导入 zzz。”

2. 使用场景

场景 A:导入第三方库或标准库
这是最标准的用法。

from datetime import datetime  # datetime 在 Python 环境的库里,直接找from django.conf import settings # django 在 site-packages 里,直接找

场景 B:项目中跨目录导入

假设目录结构如下:

myproject/├── main.py├── A/│   └── a.py -->这里面有函数 func_a1,func_a2└── B/    └── b.py --> 这里面有函数 func_b

如果你在 A/a.py 里想用 B/b.py,它们分属不同文件夹:

# 在 A/a.py 中# 此时必须用绝对导入,因为 B 不在 A 文件夹里from B.b import func_b 

前提是你在项目根目录运行程序,且根目录在 sys.path 中,如下:

# 在 main.py 写以下代码并运行,不会报错from A.a import func_a1, func_a2, func_bfunc_b()# 单独运行 A/a.py 会报错 ModuleNotFoundError: No module named 'B'

更多相关技术内容咨询欢迎前往并持续关注好学星城论坛了解详情。

想高效系统的学习Python编程语言,推荐大家关注一个微信公众号:Python编程学习圈。每天分享行业资讯、技术干货供大家阅读,关注即可免费领取整套Python入门到进阶的学习资料以及教程,感兴趣的小伙伴赶紧行动起来吧。

attachments-2022-05-rLS4AIF8628ee5f3b7e12.jpg


  • 发表于 2026-03-27 09:31
  • 阅读 ( 26 )
  • 分类:Python开发

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
Pack
Pack

1920 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 2228 文章
  3. Pack 1920 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章