Day 13:【99天精通Python】模块与包 - 代码的组织艺术

前言

欢迎来到第13天!

随着我们学的知识越来越多,写的代码也越来越长。如果把成千上万行代码都写在一个 main.py 文件里,那简直就是一场灾难:

  • 难以维护:找个函数要翻好几页。
  • 难以复用:想在别的项目里用这段代码,只能复制粘贴。
  • 命名冲突:变量名容易打架。

为了解决这个问题,Python 提供了**模块(Module)包(Package)**的概念。这就好比我们整理房间,不能把衣服、书、零食都堆在床上,而是要放进衣柜、书架和冰箱里。

本节内容:

  • 什么是模块?
  • import 的各种姿势
  • if __name__ == '__main__': 的作用
  • 什么是包?
  • Python标准库初探
  • 使用 pip 安装第三方库

一、模块 (Module):不仅是文件

1.1 什么是模块?

在 Python 中,每一个以 .py 结尾的文件就是一个模块
模块里可以包含函数、类、变量,甚至是可执行的代码。

1.2 创建和导入模块

假设我们创建了一个名为 math_tools.py 的文件:

# math_tools.py

PI = 3.14159

def add(a, b):
    return a + b

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

现在,我们在同一个目录下创建一个 main.py 来使用它。

方式 1:直接导入整个模块

# main.py
import math_tools

print(math_tools.PI)       # 访问变量
print(math_tools.add(5, 3)) # 调用函数

方式 2:从模块导入指定内容 (推荐)
这样可以直接使用函数名,不用加前缀。

# main.py
from math_tools import add, PI

print(PI)
print(add(10, 20))

方式 3:导入所有内容 (不推荐)
容易造成命名冲突,除非你非常清楚模块里有什么。

from math_tools import *

方式 4:给模块起别名 (Alias)
常用库的标准写法,如 import numpy as np

import math_tools as mt

print(mt.subtract(10, 5))

二、模块测试神器:if __name__ == ‘__main__’

这是一个初学者最容易困惑的知识点。

当我们在 math_tools.py 里写了一些测试代码:

# math_tools.py
...
print("模块被加载了!")
print(add(1, 1))

然后运行 main.py 导入它时,你会发现测试代码也被执行了!这通常不是我们想要的。

解决方法:使用 if __name__ == '__main__':

# math_tools.py

def add(a, b):
    return a + b

# 只有当直接运行 math_tools.py 时,下面代码才会执行
# 当被 import 导入时,__name__ 等于 'math_tools',下面代码不会执行
if __name__ == '__main__':
    print("正在测试 math_tools...")
    print(add(1, 1))

口诀:“我是被直接运行的(main),还是被导入的?”


三、包 (Package):模块的文件夹

当模块变多时,我们需要用文件夹来分类管理。本质上就是一个包含 __init__.py 文件的文件夹。

3.1 目录结构示例

my_project/
├── main.py
└── utils/              <-- 包 (Package)
    ├── __init__.py     <-- 标识这是一个包
    ├── file_tools.py   <-- 模块
    └── net_tools.py    <-- 模块

3.2 导入包中的模块

main.py 中调用:

# 方式 1
import utils.file_tools
utils.file_tools.save_file(...)

# 方式 2 (更常用)
from utils import file_tools
file_tools.read_file(...)

# 方式 3
from utils.net_tools import connect
connect(...)

3.3 __init__.py 的作用

  • 它可以是空的。
  • 它在包被导入时会自动执行。
  • 它可以用来控制包对外暴露哪些模块(通过 __all__ 变量)。

四、Python 标准库:内置的宝藏

Python 号称 “Batteries Included”(自带电池),意味着它内置了大量实用的模块,无需安装即可使用。

模块 用途 常用方法
os 操作系统接口 os.path.join, os.mkdir, os.listdir
sys Python解释器交互 sys.argv (命令行参数), sys.path
math 数学运算 math.sqrt, math.sin, math.pi
random 生成随机数 random.randint, random.choice, random.shuffle
datetime 日期时间 datetime.now(), strftime
time 时间控制 time.sleep(1) (暂停1秒)
json JSON数据处理 json.dumps, json.loads

示例:随机点名器

import random
import time

students = ["小明", "小红", "小刚", "小强"]

print("开始点名...")
time.sleep(1)  # 制造紧张感
lucky_dog = random.choice(students)
print(f"恭喜:{lucky_dog}!")

五、第三方库:PyPI 与 pip

Python 强大的生态系统主要体现在第三方库上(如 Pandas, Django, PyGame)。这些库存储在 PyPI (Python Package Index) 上。

5.1 安装第三方库

使用命令行工具 pip

# 安装库
pip install requests

# 指定版本安装
pip install pandas==1.3.5

# 卸载库
pip uninstall requests

# 查看已安装的库
pip list

5.2 换源(加速下载)

如果你在国内下载速度慢,可以使用镜像源:

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple requests

六、实战练习

练习1:自定义工具箱

  1. 创建一个包 my_tools
  2. 在里面创建一个模块 strings.py,包含一个函数 reverse_str(s) 用于反转字符串。
  3. 在根目录创建 main.py,导入并使用它。

目录结构

/
├── main.py
└── my_tools/
    ├── __init__.py
    └── strings.py

strings.py:

def reverse_str(s):
    return s[::-1]

main.py:

from my_tools.strings import reverse_str

text = "Python"
print(reverse_str(text))  # nohtyP

练习2:猜数字游戏(标准库应用)

使用 random 模块生成一个 1-100 的随机数,让用户循环猜测,提示"大了"或"小了",直到猜中为止。

import random

target = random.randint(1, 100)
print("我已经想好了一个1-100的数字,你猜猜看?")

while True:
    try:
        guess = int(input("请输入数字: "))
    except ValueError:
        print("请输入有效的整数!")
        continue

    if guess > target:
        print("大了!")
    elif guess < target:
        print("小了!")
    else:
        print("恭喜你,猜对了!")
        break

七、常见问题

Q1:ModuleNotFoundError 怎么办?

  1. 检查模块名有没有拼错。
  2. 如果是自己写的模块,检查文件路径是否正确,或者是否在同一个目录下。
  3. 如果是第三方库,检查是否已经 pip install

Q2:循环导入 (Circular Import) 是什么?

文件A导入了文件B,文件B又导入了文件A。
这会导致程序卡死或报错。
解决:重新设计代码结构,把公共部分提取到第三个文件C中,让A和B都去导入C。


八、小结

代码组织

模块 Module

包 Package

单文件 .py

import ...

from ... import ...

文件夹

包含 init.py

分层管理

库 Library

标准库 (os, random...)

第三方库 (pip install...)

关键要点

  1. 模块就是 .py 文件,就是带 __init__.py 的文件夹。
  2. import 导入模块,用 from ... import ... 导入具体功能。
  3. 记住 if __name__ == '__main__':,它是测试模块的好帮手。
  4. 善用标准库,避免重复造轮子。

九、课后作业

  1. 倒计时工具:编写一个程序,使用 time 模块实现一个简单的倒计时器(输入秒数,每秒打印剩余时间,最后提示"时间到")。
  2. 文件整理脚本:(综合练习) 使用 os 模块,遍历当前目录下的所有文件,将 .jpg.png 图片移动到 images 文件夹,将 .txt 移动到 docs 文件夹。
  3. 计算圆周率:查阅 math 模块文档,看看有没有直接获取 π\piπ 的属性,并计算半径为 5 的圆的周长和面积。

下节预告

Day 14:面向对象编程 (OOP) 上篇 - 类与对象 - 编程思想的重大升级!我们将开始把代码看作现实世界中的"对象"。


系列导航

  • 上一篇:Day 12 - 文件操作
  • 下一篇:Day 14 - 面向对象编程(上)(待更新)
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐