跳转到主内容
极星编程网:以代码为星,赴技术山海!

Python模块和包怎么区分_import机制解析

Python中模块是单个.py文件,包是含__init__.py的目录;import涉及查找、编译、执行、缓存全过程,并将模块对象绑定到命名空间。 Python 中的模块(module)和包(package)本质都是用于组织代码的单位,区别关键在于有没有
__init__.py
文件以及能否被 Python 识别为命名空间容器。而
import
机制是 Python 加载并执行这些单位的核心流程,它不只“导入名字”,更涉及查找、编译、执行、缓存全过程。 模块:单个 .py 文件就是最简模块 一个以
.py
结尾的文件(如
utils.py
)就是一个模块。导入时,Python 会: 在
sys.path
列表中按顺序查找该文件(包括当前目录、
site-packages
、PYTHONPATH 等) 找到后编译为字节码(
.pyc
),缓存在
__pycache__
目录下(除非禁用) 执行文件顶层代码(即缩进为 0 的语句),把所有定义(函数、类、变量)注入该模块的命名空间 将模块对象绑定到当前作用域(如
import utils
→
utils
变量指向该模块对象) 包:带 __init__.py 的目录才是包 一个包含
__init__.py
文件的目录(哪怕该文件为空)会被 Python 视为包。例如:
myproject/ ├── __init__.py ├── core.py └── helpers/ ├── __init__.py └── string.py
这时
myproject
和
myproject.helpers
都是包。关键点: Python 3.14.3 微软官方的 Python 扩展,是 VS Code 安装量最高的扩展(209M+)。集成 IntelliSense(通过 Pylance)、调试(通过 Python Debugger)、代码检查、格式化、重构和单元测试等功能。支持 Jupyter Notebook、虚拟环境管理和多 Python 版本切换。 下载 立即学习 “ Python免费学习笔记(深入) ”;
__init__.py
会在包首次被导入时自动执行,常用于设置包级变量、触发子模块导入(如
from . import core
)、定义
__all__
子模块路径用点号分隔:
import myproject.helpers.string
或
from myproject.helpers import string
相对导入只在包内有效(如
from . import core
),且必须在模块作为包的一部分运行时才合法(不能直接运行
python helpers/string.py
) import 实际发生了什么?不只是“引入名字” 执行
import A
或
from A import B
时,Python 内部调用的是
__import__()
函数(不建议手动调用),整个过程包含: 查找阶段 :通过
sys.meta_path
中的查找器(finder)尝试定位模块/包。内置查找器支持
.py
、
.pyc
、C 扩展、命名空间包等 加载阶段 :由加载器(loader)读取源码、编译、执行。包的加载会先执行其
__init__.py
缓存机制 :成功导入的模块会被存入
sys.modules
字典。后续相同 import 不再重复查找和执行,直接复用已加载的模块对象 命名绑定 :
import A
把模块对象赋给局部名
A
;
from A import B
是从模块
A
的命名空间中取出
B
绑定到当前作用域(注意:不是引用,而是新绑定) 常见误区与实用提示 理解 import 行为能避免很多“找不到模块”或“修改不生效”的问题: 修改已导入模块的源码后,
import
不会自动重载——需用
importlib.reload(module)
(仅限开发调试)
from module import x
后再
import module; module.x = ...
,不会影响已导入的
x
,因为它是独立对象引用 循环导入不一定报错,但可能因模块未完全初始化导致属性缺失(如 A 导入 B,B 又在顶层导入 A,此时 A 的部分代码还没执行完) 想让包支持
from package import *
,需在
__init__.py
中定义
__all__ = ['func1', 'ClassA']

相关文章