Python中Package导入机制与模块访问详解

Theo
Theo
发布时间:2026-10-15| 6人浏览过
原创

本文深入解析Python中Package的导入机制,区分Regular Package与Namespace Package。重点讲解__init__.py的作用、pkg.__path__与pkg.__file__属性的区别,以及import pkg与import pkg.mod1在sys.modules缓存和全局变量中的行为差异,帮助开发者正确访问子模块。

Python Package与Module的基本概念

在Python中,Package是组织代码的有效方式。Module通常对应单个文件,可通过import语句导入;而Package则对应一个目录结构。接下来我们将探讨多层嵌套目录下的导入方式。

>>> import collections,socket
>>> print(collections.__path__)
['/anaconda3/envs/py38/lib/python3.8/collections']
>>> print(socket.__path__)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'socket' has no attribute '__path__'

以Python标准库为例,collections是一个Package(目录结构),而socket是一个Module(单个文件)。两者的关键区别在于Package具有__path__属性,可通过__path__访问存放Python文件的目录路径,而普通Module不具备此属性。

Python Package的两种类型

Python中主要存在两种Package类型:Regular Package(常规包)和Namespace Package(命名空间包)。

Regular Package是最常见的包形式。

Regular Package结构与__init__.py作用

首先分析Regular Package的结构。

main.py
pkg1
---__init__.py

在项目目录下创建文件夹pkg1,并在其中放置文件__init__.py,该目录即构成Regular Package。包名即为文件夹名,可直接导入。在__init__.py文件中添加如下代码。

print("importing pk1")
def hi_say():
    print("pkg1 say hi")

在main.py中执行import pkg1语句。Python通过Finder定位Package位置,PathFinder在sys.path中搜索。由于sys.path首个路径为当前目录,Python能定位到pkg1。导入Package时,会自动执行其下的__init__.py文件。导入后生成的编译代码对象,可通过pkg1.hi_say()调用。

print(pkg1.__path__)

利用pkg1的__path__属性,可获取pkg1目录的绝对路径。

print(pkg1.__file__)

通过__file__属性,可得到__init__.py文件的绝对路径。

print(pkg1.__package__)

此外,可通过Package的__package__属性获取Package名称,或通过__name__获取Module名称。

Package下子Module的导入与访问机制

进一步增加复杂度,在pkg1文件夹下新建mod1.py文件。

main.py
 pkg1
 ---__init__.py
 ---mod1.py

__init__.py文件内容如下。


print("importing pk1")

在mod1.py中输出“import mod1”信息,并定义say_hi函数。目标是导入该Module并执行其中的say_hi方法。

print("importing mod1")
def say_hi():
    print("pkg1 say hi")
import sys
import pkg1

print('pkg1' in globals())#True
print('pkg1' in sys.modules)#True

执行import pkg1时,会创建指向Module对象的引用并加入全局变量,同时该Module会被添加到sys.modules缓存中。

若直接通过pkg1.mod1访问mod1 Module,将抛出错误,提示该属性不存在。

AttributeError: module 'pkg1' has no attribute 'mod1'

这表明仅导入Package并不会自动导入其下的子Module,因此会出现上述错误。要正确导入pkg1下的mod1,需使用import pkg1.mod1这种标准方式。

import sys
import pkg1.mod1

请注意,正确导入mod1的方式是import pkg1.mod1。从输出结果可见,Python先执行__init__.py,即先导入Package pkg1,随后再导入Module mod1,遵循此顺序。

importing pk1
importing mod1

采用上述方式即可访问Module mod1中的say_hi()方法。

pkg1.mod1.say_hi()
print('pkg1' in sys.modules)#True
print('pkg1.mod1' in sys.modules)#True
print('pkg1' in globals())#True
print('pkg1.mod1' in globals())#False

观察输出可知,pkg1和pkg1.mod1均存在于sys.modules缓存中。但仅pkg1位于全局变量中,必须通过pkg1的属性来访问mod1。

简要总结:要访问Package下的Module,首先访问Package会执行其下的__init__.py文件,随后执行Module代码。sys.modules中保存pkg1和pkg1.mod1分别指向两个Module对象的内存地址。

至此,关于如何在Python中导入Package的文章介绍完毕。更多相关内容请搜索本站历史文章或继续浏览后续文章,感谢支持!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。