
大家好,我是煜道。
今天我们一起来学习 模块与包。
引言
随着程序规模的增长,将所有代码放在单个文件中变得难以维护。Python提供了模块和包机制,允许我们将代码组织成可重用的单元。模块是包含Python定义和语句的文件,包是组织多个模块的目录结构。理解模块和包的使用对于构建大型Python应用至关重要。
本文将深入探讨Python的模块系统,包括模块的导入机制、包的结构、相对导入、模块的内置变量以及包的分发和安装。通过本文的学习,我们将能够合理地组织Python代码,并理解第三方库的安装和使用原理。

01 模块的基本概念
1.1 什么是模块
在Python中,一个.py文件就是一个模块。模块可以包含函数、类、变量和可执行语句。
# mymodule.py"""这是我的模块"""defgreet(name):returnf"Hello, {name}!"PI = 3.14159classCalculator:defadd(self, a, b):return a + b
1.2 导入模块
Python提供了多种导入模块的方式:
# 导入整个模块import mathprint(math.sqrt(16)) # 4.0# 导入模块并指定别名import numpy as npprint(np.array([1, 2, 3]))# 导入模块中的特定内容from math import sqrt, piprint(sqrt(16) * pi) # 12.56636# 导入模块中的所有内容(不推荐)from math import *print(sin(0)) # 0.0# 导入并指定别名from collections import OrderedDict as OD

1.3 模块的搜索路径
当导入模块时,Python按照以下顺序搜索:
- 安装的第三方包目录(site-packages)。
import sys# 查看模块搜索路径print(sys.path)# 添加自定义路径sys.path.append('/path/to/my/modules')
1.4 模块的导入执行
模块在首次导入时会被执行:
# example.pyprint("模块导入时会被执行!")defhello(): print("Hello!")# 只在直接运行时执行if __name__ == "__main__": print("This module is run directly")else: print(f"This module is imported as {__name__}")


02 包的结构
2.1 什么是包
包是包含__init__.py文件的目录,用于组织多个模块。
my_package/├── __init__.py├── module_a.py├── module_b.py└── sub_package/ ├── __init__.py └── module_c.py
2.2 init.py文件
__init__.py文件可以为空,也可以包含包的初始化代码和导入声明:
# my_package/__init__.py# 从子模块导入常用内容from .module_a import func_afrom .module_b import func_b# 定义包的版本__version__ = "1.0.0"# 配置包的公共接口__all__ = ['func_a', 'func_b', 'SubClass']
2.3 包的导入
# 导入包import my_package# 导入包中的模块import my_package.module_a# 导入包中的子包import my_package.sub_package.module_c# 导入包中的函数from my_package.module_a import func_a# 相对导入from . import module_a # 从当前包导入from .sub_package import module_c # 从子包导入

03 相对导入与绝对导入
3.1 相对导入
相对导入使用点号(.)表示当前包,双点号(..)表示上级包:
# my_package/module_a.pyfrom .module_b import func_b # 导入同一包中的module_bfrom .sub_package.module_c import func_c # 导入子包中的模块# 导入当前包中的内容from . import helper
3.2 绝对导入
绝对导入使用完整的包路径:
from my_package.module_a import func_afrom my_package.sub_package.module_c import func_c
3.3 导入方式对比
| | | |
|---|
| from package import module | | |
| from . import module | | |

3.4 入口文件与相对导入
重要:直接运行的Python文件不能使用相对导入。如果需要在入口文件中使用相对导入,需要以模块方式运行:
# 错误:直接运行时不能使用相对导入# python my_package/main.py # 报错# 正确:以模块方式运行# python -m my_package.main# 或者在入口文件中使用绝对导入import my_package.module_a

04 模块内置变量
4.1 name
__name__是一个特殊的内置变量,用于判断模块的执行方式:
# module.pydefmain(): print(f"Running as {__name__}")if __name__ == "__main__": main()
4.2 其他内置变量
# module.pyprint(__name__) # 模块名print(__file__) # 模块文件路径print(__doc__) # 模块文档字符串print(__package__) # 包名print(__spec__) # 模块规范信息print(__annotations__) # 类型注解
# 完整示例"""example_module.py这是一个示例模块"""defhello():"""打招呼函数""" print("Hello from example_module!")if __name__ == "__main__": print(f"Module name: {__name__}") print(f"Module file: {__file__}") print(f"Module doc: {__doc__}") hello()

05 常用标准库模块
5.1 os模块——操作系统接口
import os# 文件和目录os.getcwd() # 获取当前工作目录os.chdir('/path') # 更改当前目录os.listdir('.') # 列出目录内容os.mkdir('dirname') # 创建目录os.makedirs('a/b/c') # 递归创建目录# 路径操作import os.path as pathpath.join('dir', 'file.txt') # 路径拼接path.exists('file.txt') # 文件是否存在path.isfile('file.txt') # 是否为文件path.isdir('dirname') # 是否为目录path.basename('/path/file.txt') # 文件名path.dirname('/path/file.txt') # 目录名# 系统信息os.name # 'posix' 或 'nt'os.environ # 环境变量字典os.getlogin() # 当前用户名
5.2 sys模块——系统功能
import sys# 命令行参数sys.argv # 脚本参数列表# 标准流sys.stdin # 标准输入sys.stdout # 标准输出sys.stderr # 标准错误# Python信息sys.version # Python版本sys.executable # Python解释器路径sys.path # 模块搜索路径sys.modules # 已导入模块字典# 退出程序sys.exit(0) # 正常退出
5.3 pathlib模块——面向对象的路径操作
from pathlib import Pathp = Path('/home/user/documents')# 路径组件p.parts # ('/', 'home', 'user', 'documents')p.name # 'documents'p.stem # 'documents'p.suffix # ''p.parent # /home/user# 路径操作p / 'file.txt'# 路径拼接p.exists() # 是否存在p.is_dir() # 是否为目录p.is_file() # 是否为文件# 目录遍历list(p.glob('*.py')) # 所有Python文件list(p.rglob('**/*.py')) # 递归遍历# 创建和删除p.mkdir(parents=True, exist_ok=True)p.rmdir() # 删除空目录
5.4 其他常用模块
# json - JSON处理import jsondata = {'name': 'Python', 'version': 3.12}json_str = json.dumps(data)parsed = json.loads(json_str)# datetime - 日期时间from datetime import datetime, date, timedeltanow = datetime.now()today = date.today()tomorrow = today + timedelta(days=1)# collections - 容器数据类型from collections import Counter, defaultdict, OrderedDictcnt = Counter('abracadabra')d = defaultdict(list) # 默认值为list的字典# itertools - 迭代工具import itertoolslist(itertools.chain([1, 2], [3, 4])) # [1, 2, 3, 4]list(itertools.combinations([1, 2, 3], 2)) # [(1, 2), (1, 3), (2, 3)]# functools - 函数工具from functools import reduce, lru_cache@lru_cache(maxsize=128)deffib(n):return fib(n-1) + fib(n-2) if n > 1else n


06 小结
本文系统介绍了Python的模块和包系统:
- 模块导入:import、from import、模块搜索路径。
- 包结构:包是包含
__init__.py的目录,用于组织模块。 - 内置变量:
__name__、__file__、__doc__等。
掌握模块和包的组织方式对于构建可维护的Python应用至关重要。在实际开发中,应该合理划分代码模块,编写清晰的文档字符串。
