Python模块导入之import、from、相对导入与 init.py详解

 更新时间:2025年09月19日 08:27:15   作者:a.原味瓜子  
在Python中,import 和 from import 是两种导入模块或模块中特定内容的语法,它们的用法和适用场景有所不同,这篇文章主要介绍了Python模块导入之import、from、相对导入与 init.py的相关资料,需要的朋友可以参考下

前言

在 Python 开发中,模块和包是组织代码的核心方式,而 import 和 from 则是实现代码复用的基础工具。本文将深入解析 Python 的导入机制,包括 import 与 from 的用法差异、. 在相对导入中的作用,以及 __init__.py 文件的核心功能,帮助你构建清晰、可维护的模块化项目。

一、模块与包:导入的基础

在讨论导入语法前,我们需要明确两个基本概念:

  • 模块(Module):一个以 .py 为扩展名的 Python 文件,包含函数、类、变量和可执行代码。例如 utils.py 就是一个模块。
  • 包(Package):包含多个模块的文件夹,必须包含 __init__.py 文件(可空)。例如 my_package/ 文件夹下有 __init__.py 和多个 .py 文件,就是一个包。

示例项目结构

my_project/
├── main.py               # 主程序
├── math_utils.py         # 单个模块
└── my_package/           # 包
    ├── __init__.py       # 包标识文件
    ├── data.py           # 子模块
    └── subpackage/       # 子包
        ├── __init__.py
        └── process.py    # 子包中的模块

二、import:导入整个模块

import 关键字用于导入整个模块,语法为:

import 模块名

导入后需通过 模块名.成员 的方式使用模块中的函数、类或变量。

基本用法

# 导入标准库模块
import math
print(math.sqrt(16))  # 输出:4.0(通过模块名访问成员)

# 导入自定义模块(与当前脚本同目录)
import math_utils
print(math_utils.add(2, 3))  # 调用自定义模块中的add函数

进阶技巧:别名与多模块导入

  • 用 as 给模块起别名,简化调用:

    import pandas as pd  # 约定俗成的别名
    df = pd.DataFrame()
    
  • 一行导入多个模块(推荐分开写以提高可读性):

    import os, sys, json  # 不推荐
    import os
    import sys
    import json  # 推荐
    

三、from ... import:导入特定成员

from ... import 用于从模块中直接导入指定成员,语法为:

from 模块名 import 成员1, 成员2

导入后可直接使用成员名,无需前缀。

基本用法

# 从模块导入特定成员
from math import pi, sqrt
print(pi)  # 输出:3.141592653589793(直接使用成员)
print(sqrt(25))  # 输出:5.0

# 从自定义模块导入类
from my_package.data import User
user = User("Alice")  # 直接使用类

进阶技巧:别名与通配符

  • 用 as 解决命名冲突:

    from math import pow as math_pow
    
    def pow(a):
        return a * a
    
    print(pow(2))       # 调用自定义函数:4
    print(math_pow(2, 3))  # 调用math模块的函数:8.0
    
  • 用 * 导入所有公开成员(谨慎使用):

    from math import *  # 导入math模块所有公开成员
    print(sin(pi/2))  # 输出:1.0
    
     

    ⚠️ 注意:* 可能导致命名冲突,且无法清晰追溯成员来源,大型项目中不推荐使用。

四、. 的作用:相对导入

. 在导入语法中表示包的层级关系,用于包内部的模块之间进行相对导入,类似文件系统中的 .(当前目录)和 ..(父目录)。

相对导入的场景

当你需要在包内部的模块中导入同包的其他模块时,相对导入能避免硬编码包名,增强代码可移植性。

示例:在 my_package/subpackage/process.py 中导入上层模块:

# my_package/subpackage/process.py

# 导入同目录(subpackage)下的其他模块
from . import helper  # . 表示当前包(subpackage)

# 导入父目录(my_package)下的data模块
from .. import data  # .. 表示父包(my_package)

# 导入父目录下模块中的成员
from ..data import User

相对导入的规则

  • . 表示当前包 / 目录
  • .. 表示父包 / 父目录
  • ... 表示祖父包(以此类推,层级不宜过深)
  • 只能在包内部使用,直接运行含相对导入的脚本会报错

绝对导入 vs 相对导入

类型语法示例适用场景
绝对导入from my_package import data包外导入或跨包导入
相对导入from .. import data包内部模块之间的导入

五、init.py:包的 “配置文件”

__init__.py 是 Python 包的标识文件,放在包目录下,用于控制包的导入行为。它可以是一个空文件,也可以包含 Python 代码。

核心功能 1:标识包

文件夹中只要包含 __init__.py,Python 就会将其识别为一个包,否则视为普通文件夹,无法进行包导入。

核心功能 2:控制 from package import *

通过 __all__ 变量定义 from package import * 时能导入的模块列表:

# my_package/__init__.py
__all__ = ["data", "subpackage"]  # 仅允许导入这两个模块/子包

此时执行 from my_package import * 时,只会导入 data 和 subpackage

核心功能 3:包初始化代码

__init__.py 中的代码会在包被导入时自动执行,可用于初始化包的资源:

# my_package/__init__.py
print("my_package 被导入了")  # 导入时执行

# 定义包级别的变量或函数
VERSION = "1.0.0"

def get_version():
    return VERSION

导入包时会执行上述代码:

import my_package  # 输出:my_package 被导入了
print(my_package.VERSION)  # 输出:1.0.0

核心功能 4:简化导入路径

通过 __init__.py 可以将子模块的成员提升到包级别,简化导入:

# my_package/__init__.py
from .data import User  # 将data模块的User类提升到包级别

之后可以直接从包导入 User,无需指定子模块:

from my_package import User  # 简化导入路径

六、常见问题与最佳实践

1. 避免循环导入

当模块 A 导入模块 B,同时模块 B 导入模块 A 时,会引发 ImportError。解决方法:

  • 重构代码,将共享逻辑提取到新模块
  • 将导入语句移到函数内部(延迟导入)

2. 相对导入报错

运行含相对导入的脚本时出现 ImportError: attempted relative import with no known parent package,原因是脚本被视为独立模块而非包的一部分。解决方法:

  • 通过包外脚本导入该模块(推荐)
  • 使用 -m 参数以模块方式运行:python -m my_package.subpackage.process

3. 最佳实践

  • 优先使用绝对导入,代码更清晰
  • 包内部使用相对导入,避免硬编码包名
  • 不滥用 from ... import *,减少命名冲突
  • __init__.py 保持简洁,仅包含必要的初始化逻辑

总结

Python 的导入机制是模块化编程的基础,掌握 import 与 from 的用法差异,理解 . 在相对导入中的作用,以及 __init__.py 的配置功能,能帮助你构建层次清晰、易于维护的项目结构。合理的导入策略不仅能提高代码复用率,还能让项目更具可扩展性。

希望本文能帮你理清 Python 导入的核心概念,在实际开发中灵活运用这些工具!

到此这篇关于Python模块导入之import、from、相对导入与 init.py的文章就介绍到这了,更多相关Python模块导入详解内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • python 实现两个字符串乘法小练习

    python 实现两个字符串乘法小练习

    这篇文章主要给大家分享的是python 实现两个字符串乘法小练习,两个字符串相乘,基本思路是num1依次乘以num2各个数位上的数字,下面分享的内容,可作为大家平时学习的小练习,需要的朋友可以参考下,希望对你的学习有所帮助
    2022-02-02
  • 基于python的图片修复程序(实现水印去除)

    基于python的图片修复程序(实现水印去除)

    这篇文章主要给大家介绍了关于python图片修复程序的相关资料,可以用于实现图片中水印去除,主要利用的是OpenCV这个框架实现的,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面来一起看看吧
    2018-06-06
  • 基于Python实现复刻人生重开模拟器

    基于Python实现复刻人生重开模拟器

    人生重开模拟器是由VickScarlet上传至GitHub的一款简单的文字网页游戏。本文将用Python复刻一下这个游戏,感兴趣的小伙伴可以尝试一下
    2022-10-10
  • pandas报错AttributeError: DataFrame object has no attribute ix问题

    pandas报错AttributeError: DataFrame object has&

    这篇文章主要介绍了pandas报错AttributeError: DataFrame object has no attribute ix问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-02-02
  • numpy中矩阵合并的实例

    numpy中矩阵合并的实例

    今天小编就为大家分享一篇numpy中矩阵合并的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-06-06
  • 分享5个数据处理更加灵活的pandas调用函数方法

    分享5个数据处理更加灵活的pandas调用函数方法

    这篇文章主要介绍了分享5个数据处理更加灵活的pandas调用函数方法,文章基于python的相关内容展开详细介绍,需要的小伙伴可以参考一下
    2022-04-04
  • OpenCV半小时掌握基本操作之圆圈检测

    OpenCV半小时掌握基本操作之圆圈检测

    这篇文章主要介绍了OpenCV基本操作之圆圈检测,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-09-09
  • python爬虫抓取时常见的小问题总结

    python爬虫抓取时常见的小问题总结

    这篇文章主要介绍了python爬虫抓取时常见的小问题总结,整理了部分新手在爬虫过程中遇到的问题,希望可以给大家提供一点问题解决的思路和参考,需要的小伙伴可以参考下面文章内容
    2022-05-05
  • Python中的随机函数random详解

    Python中的随机函数random详解

    大家好,本篇文章主要讲的是Python中的随机函数random详解,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
    2021-12-12
  • python自动裁剪图像代码分享

    python自动裁剪图像代码分享

    这篇文章主要介绍了python自动裁剪图像代码分享,具有一定参考价值,需要的朋友可以了解下。
    2017-11-11

最新评论