跳转至

模块与包 (Modules and Packages)

随着代码量的增加,将所有代码写在一个文件中会变得难以维护。Python 提供了模块 (Module)包 (Package) 的机制,帮助我们要组织和管理代码结构。

1. 什么是模块?

简单来说,一个 .py 文件就是一个模块。模块中可以包含函数、类和变量。

假设我们有一个文件 my_math.py

# my_math.py
def add(a, b):
    return a + b

def subtract(a, b):
    return a - b

PI = 3.14159

导入模块

我们可以使用 import 语句在其他文件中使用这个模块。

import my_math

print(my_math.add(1, 2))
print(my_math.PI)

导入特定成员

使用 from ... import ... 可以只导入需要的部分,这样可以直接使用函数名而不需要模块名前缀。

from my_math import add, PI

print(add(1, 2))
print(PI)

给模块起别名

使用 as 关键字可以给长模块名起个简短的别名。

import my_math as mm

print(mm.add(1, 2))

2. if __name__ == "__main__":

这是一个非常常见的惯用写法。

  • 当模块被直接运行时,__name__ 的值为 "__main__"
  • 当模块被导入时,__name__ 的值为模块的名字(如 "my_math")。

这允许我们在模块中包含一些测试代码,这些代码只在直接运行模块时执行,而被导入到其他程序时不会执行。

# my_math.py
def add(a, b):
    return a + b

if __name__ == "__main__":
    print("Running as main program")
    print("Testing add function:", add(1, 1))

3. 什么是包?

包 (Package) 是一个包含多个模块的目录。在 Python 3.3 之前,目录下必须包含一个 __init__.py 文件才能被视为包(虽然现在不是必须的,但保留它仍是一个好习惯,用于标识包被初始化时的逻辑)。

假设有如下目录结构:

my_project/
    main.py
    utils/
        __init__.py
        string_utils.py
        file_utils.py

我们可以这样导入:

# main.py
from utils import string_utils
# 或者
from utils.string_utils import to_upper

__init__.py 的作用

__init__.py 可以为空,也可以包含包的初始化代码,或者通过 __all__ 变量控制 from package import * 时导出的模块。

# utils/__init__.py
print("Initializing utils package...")
# 可以在这里预先导入子模块,方便外部调用
from .string_utils import to_upper

这样外部就可以直接 from utils import to_upper 了。

4. 绝对导入 vs 相对导入

  • 绝对导入:从项目根目录开始导入,如 from utils.string_utils import ...。(推荐
  • 相对导入:使用 . 表示当前目录,.. 表示上级目录,如 from . import string_utils。(通常用于包内部模块之间的互相引用)

5. 标准库与第三方库

  • 标准库:Python 自带的库,直接导入即可,如 os, sys, math, datetime, json 等。
  • 第三方库:需要通过 pip install 安装的库,如 requests, numpy, pandas 等。

总结

  • 模块就是一个 .py 文件,包是一个包含模块的目录。
  • 使用 importfrom ... import 导入代码。
  • 利用 if __name__ == "__main__": 区分脚本运行和模块导入。
  • 合理的模块化设计能让代码结构清晰、易于复用和维护。

下一步

现在我们已经学会了如何组织代码,接下来我们将学习如何处理更复杂的数据交换和文件操作,比如 JSON 序列化、CSV 处理以及更优雅的路径操作库 pathlib

👉 前往下一章:进阶输入输出 (Advanced I/O)