Python绝对导入和相对导入的区别和用法详解

 更新时间:2026年08月05日 09:26:58   作者:星河耀银海  
还在纠结Python绝对导入和相对导入怎么选,本文用生活化比喻讲清两种指路方式,绝对导入用完整路径清晰安全,相对导入更灵活但有限制,看完这篇包内导入对比指南,你就能避开常见坑,写出可维护的代码,需要的朋友可以参考下

一、开篇:两种指路方式

在包内部,一个模块要导入同包中的另一个模块,有两种方式:绝对导入相对导入

先感受区别:

# 假设包结构:
# mypackage/
# ├── __init__.py
# ├── core.py
# ├── utils.py
# └── sub/
#     ├── __init__.py
#     └── helper.py

# ===== mypackage/sub/helper.py =====

# 绝对导入——从项目根开始的完整路径
from mypackage.core import some_function  # 绝对路径
from mypackage.utils import format_data   # 绝对路径

# 相对导入——使用.和..的相对路径
from ..core import some_function    # .. 表示上一级(mypackage)
from ..utils import format_data     # .. 表示上一级(mypackage)
from . import __init__ as sub_init  # . 表示当前包(sub)

绝对导入用"完整地址",相对导入用"当前所在位置+方向"。两种方式各有优劣,理解它们的区别是构建可维护Python项目的关键。

二、相对导入详解

2.1 语法规则

# 相对导入的语法:
# from . import module        —— 从当前包导入module
# from .module import name    —— 从当前包的module中导入name
# from .. import module       —— 从上级包导入module
# from ..subpkg import module —— 从上级包的subpkg中导入module
# from ... import module      —— 从上上级包导入(很少用)

# 相对导入使用示例:

# 在 mypackage/sub/helper.py 中:
# .         → mypackage/sub/       (当前目录)
# ..        → mypackage/            (上级目录)
# ...       → 项目根目录             (上上级)
# .module   → mypackage/sub/module  (同目录下的模块)

# 具体使用:
# from . import sibling_module     # 同目录的兄弟模块
# from .. import core              # 上级目录的core模块
# from ..utils import format_data  # 上级目录utils模块中的format_data

2.2 相对导入的限制

# ⚠️ 相对导入只能在包内部使用!
# 不能直接在顶层脚本中使用相对导入

# ===== main.py (顶层脚本) =====
# from . import something  # ❌ 错误!
# ImportError: attempted relative import with no known parent package
# 顶层脚本不是包的一部分,没有"上级包"的概念

# ===== mypackage/module_a.py =====
# from .. import something  # ✅ 正确——module_a在包内部

# ⚠️ 另一个常见错误:
# python mypackage/module_a.py  # 直接运行包内的模块
# 这会把module_a当作顶层脚本——相对导入失败!
# 正确方式:python -m mypackage.module_a

三、绝对导入详解

3.1 绝对导入的写法

# 绝对导入——从项目的"根"开始的完整路径

# 假设项目结构:
# myproject/
# ├── mypackage/
# │   ├── __init__.py
# │   ├── core.py
# │   └── utils.py
# └── main.py

# 在mypackage/core.py中:
# 绝对导入——完整的"地址"
from mypackage.utils import helper_function
import mypackage.utils

# 在main.py中:
from mypackage.core import CoreClass
import mypackage

# ✅ 绝对导入的优点:
# 1. 清晰——一眼看出导入的是什么
# 2. 可移植——把代码移到别处,导入路径不变
# 3. 可读——新人看代码容易理解
# 4. 安全——不容易因为文件移动而出错

# ❌ 绝对导入的缺点:
# 1. 路径可能很长(深层嵌套时)
# 2. 改包名时需要更新所有导入
# 3. 重命名顶层包名很痛苦

3.2 绝对导入 vs 相对导入的对比

# 同一个导入,两种写法:

# 在 mypackage/sub/deep/nested/module.py 中
# 需要导入 mypackage/utils.py 中的函数

# 绝对导入:
from mypackage.utils import format_data
# 很长,但意图明确

# 相对导入:
from ...utils import format_data
# 简短的...但你需要数一下有几层

# 💡 直观对比:

# 绝对导入:写全了"地址"
# from myproject.users.models import User
# from myproject.users.services import UserService

# 相对导入:用"方位"描述
# from .models import User
# from ..services import UserService

四、选型建议

# ✅ 使用绝对导入的场景:

# 1. 外部/公共API的导入
from mypackage import UserService  # 清晰明了

# 2. 跨大层级导入(避免写很多...)
from myproject.config import settings  # 比 ../../../config 好

# 3. 顶层脚本和测试文件
# tests/test_user.py:
from mypackage.services.user_service import UserService

# 4. 开源项目——绝对导入对用户更友好
# 用户更容易理解导入路径

# ✅ 使用相对导入的场景:

# 1. 包内部紧密关联的模块
# mypackage/models/user.py 导入 mypackage/models/base.py:
from .base import BaseModel  # 简短自然

# 2. 大型包内部——重构友好
# 移动整个子包时,内部相对导入不需要修改
# mypackage/sub/ 从 mypackage/ 移到 mypackage/core/
# 包内部的 . 和 .. 导入不受影响

# 3. __init__.py中的重新导出
# mypackage/__init__.py:
from .subpkg.module import Class  # 简洁

# 💡 团队建议:
# 大多数项目:优先使用绝对导入
# 大型包内部紧密关联时:使用相对导入
# 绝对不要混用——一个项目中保持一致!

五、常见问题和解决

# 问题一:"Attempted relative import in non-package"
# 原因:在顶层脚本中使用了相对导入
# 解决:改用绝对导入,或用 python -m 运行模块

# 问题二:"No module named 'xxx'"
# 原因:绝对导入时包名不对、或包不在sys.path中
# 解决:检查包名、检查目录结构

# 问题三:移动文件后导入全部失效
# 原因:使用了绝对导入,包名或路径变了
# 解决:如果是包内部移动,相对导入更健壮

# 问题四:循环导入
# 原因:两个模块互相导入对方
# 解决:重构代码、延迟导入(在函数内部import)

六、总结

绝对导入和相对导入是两种不同的"指路"方式。绝对导入用完整地址,相对导入用方向和距离。

核心要点:

  1. 绝对导入from mypackage.module import name——完整路径,清晰可读
  2. 相对导入from .module import name——使用...的相对路径
  3. 相对导入限制:只能在包内部使用,顶层脚本不可用
  4. 大多数场景推荐绝对导入——更清晰、更安全
  5. 包内部紧密关联时用相对导入——更灵活、重构友好

一句话:对外用绝对,对内可相对。保持一致最重要。

以上就是Python绝对导入和相对导入的区别和用法详解的详细内容,更多关于Python绝对导入和相对导入的资料请关注脚本之家其它相关文章!

相关文章

  • Python装饰器的练习题

    Python装饰器的练习题

    这篇文章主要给大家分享的是 Python装饰器的练习题,习题不多,就三个基础练习题,需要的朋友可以参考一下,希望对你有所帮助
    2021-11-11
  • Python使用TCP和UDP协议向IP地址发送字符串的代码示例

    Python使用TCP和UDP协议向IP地址发送字符串的代码示例

    在 Python 中,向特定的 IP 地址发送字符串通常是通过网络协议来实现的,常见的协议包括 TCP(传输控制协议)和 UDP(用户数据报协议),本文将详细介绍如何使用 TCP 和 UDP 协议向指定的 IP 地址发送字符串,并提供相应的代码示例,需要的朋友可以参考下
    2025-07-07
  • python特效之字符成像详解

    python特效之字符成像详解

    这篇文章主要为大家介绍了python特效之字符成像,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-01-01
  • 详解如何使用python脚本制作生成CANdbc

    详解如何使用python脚本制作生成CANdbc

    这篇文章主要为大家详细介绍了如何使用python脚本制作生成CANdbc,文中的示例代码讲解详细,具有一定的学习价值,感兴趣的小伙伴可以了解下
    2024-01-01
  • 浅谈一下Python究竟属不属于嵌入式语言

    浅谈一下Python究竟属不属于嵌入式语言

    这篇文章主要介绍了浅谈一下Python究竟属不属于嵌入式语言,大家普遍的认为C与C++才是标准的嵌入式语言,那么现在大火的Python算是一种嵌入式语言吗,需要的朋友可以参考下
    2023-04-04
  • python 教程实现 turtle海龟绘图

    python 教程实现 turtle海龟绘图

    这篇文章主要介绍了python 教程实现 turtle绘制海龟绘图,文章基于python的相关资料展开turtle绘制海龟绘图的详细内容,需要的小伙伴可以参考一下
    2022-05-05
  • python networkx 根据图的权重画图实现

    python networkx 根据图的权重画图实现

    这篇文章主要介绍了python networkx 根据图的权重画图实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-07-07
  • OpenCV实战案例之车道线识别详解

    OpenCV实战案例之车道线识别详解

    计算机视觉在自动化系统观测环境、预测该系统控制器输入值等方面起着至关重要的作用,下面这篇文章主要给大家介绍了关于OpenCV实战案例之车道线识别的相关资料,需要的朋友可以参考下
    2022-10-10
  • Linux 下 Python 实现按任意键退出的实现方法

    Linux 下 Python 实现按任意键退出的实现方法

    这篇文章主要介绍了Linux 下 Python 实现按任意键退出的实现方法的相关资料,本文介绍的非常详细,具有参考借鉴价值,需要的朋友可以参考下
    2016-09-09
  • Python3 关于pycharm自动导入包快捷设置的方法

    Python3 关于pycharm自动导入包快捷设置的方法

    今天小编就为大家分享一篇Python3 关于pycharm自动导入包快捷设置的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-01-01

最新评论