You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中从文件夹与包导入模块的区别及输出差异解析

普通目录与Python包的区别及输出差异解析

一、核心区别:命名空间包 vs 常规包

Python 3.3之后引入了命名空间包的特性,这就是你看到“没有__init__.py也能导入目录下模块”的原因,它和传统的常规包(带__init__.py)的核心区别如下:

  • 存在形式:
    • 常规包:必须有__init__.py文件,这个文件就是包本身的模块载体。
    • 命名空间包:不需要任何特殊文件,只是Python为了组织跨路径模块而创建的虚拟命名空间容器。
  • 加载逻辑:
    • 常规包:导入时会执行__init__.py里的所有代码,你可以在这里定义包级变量、统一导入子模块、控制对外暴露的接口(比如用__all__)。
    • 命名空间包:导入时不会执行任何代码,它唯一的作用就是让你能用folder1.b这种层级结构访问子模块,本身没有实际的代码逻辑。

二、你的输出差异到底是什么意思

无__init__.py时的输出

20
<module 'folder1' (namespace)>
<module 'folder1.b' from '/path/to/study_import/folder1/b.py'>

这里的folder1是命名空间模块,标记(namespace)说明它只是个空的命名空间容器,没有对应的.py文件,Python创建它只是为了让你能通过层级路径访问子模块b。

添加__init__.py后的输出

20
<module 'folder1' from '/path/to/study_import/folder1/__init__.py'>
<module 'folder1.b' from '/path/to/study_import/folder1/b.py'>

此时folder1变成了常规包模块,它直接对应你创建的__init__.py文件,Python导入包时会执行这个文件里的代码,所以输出明确显示了它的来源是__init__.py。你可以在这个文件里做很多事情,比如:

# folder1/__init__.py
# 统一导入子模块的变量,让用户直接import folder1就能用VAR2
from .b import VAR2
# 控制from folder1 import *时能导入的内容
__all__ = ['VAR2']

三、其他值得注意的差异

  • 包级功能:常规包可以通过__init__.py实现包级别的配置、初始化逻辑,而命名空间包做不到,因为它没有可执行的文件。
  • 兼容性:命名空间包是Python 3.3+才支持的特性,如果要兼容Python 2.x,必须使用带__init__.py的常规包。

内容的提问来源于stack exchange,提问作者User051209

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 06:02:05