完整讲解 · 6 段教学·配 4 道练习题·预计 35 分钟
本页是本章的通读版,可直接读完全部讲解。想动手写代码、跑判分,去 闯关模式。
到这一节,Python 基础学习就接近尾声了。
这一节学的是 模块——把代码按功能切分、复用别人写好的代码的关键工具。
import / from···import / from ··· import *__name__ == '__main__')提示:本节的练习全部使用 Python 内置标准库(math / random / datetime / json 等),不会让你创建额外的
.py文件。
随着代码越写越多,把所有代码都堆到一个文件里会越来越难维护。
之前我们学过:
而 模块 比类更高一级——一个模块里可以放变量、函数、类。
┌─────────────────────┐
│ 模块 │
│ │
│ 变量 │
│ │
│ 函数 │
│ │
│ ┌────────────────┐ │
│ │ 类 │ │
│ │ 变量1/变量2... │ │
│ │ 函数1/函数2... │ │
│ └────────────────┘ │
└─────────────────────┘
封装函数用 def,封装类用 class,封装模块不需要任何关键字——
在 Python 中,一个
.py文件就是一个模块(Module)。
Python 自带了很多非常有用的模块(叫 标准库),装好 Python 就能用,比如 math、random、datetime、json、os、sys ……
模块大致分两类:
math.py 文件pip install 安装的本节练习主要用标准库。
要使用某个模块,必须先 导入。导入的关键字是 import。
最基本的语法:
import 模块名也可以一次导入多个:
import module1, module2, module3例子——使用标准库 math 模块的 pi 属性:
import math
print(math.pi)输出:
3.141592653589793
一个模块只会被导入一次,不管你写了多少次
import。重复import不会重复执行模块代码。
import math 只是把 math 这个模块整体引进来,使用里面的东西必须写前缀(math.pi、math.sqrt(...))。
如果只想用模块里的某一个函数或属性,可以直接 挑出来导入:
from 模块名 import 名字1, 名字2, ...对比一下:
# 写法 1:import 整个模块
import math
print(math.pi) # 必须写 math. 前缀
# 写法 2:from···import 直接拎出来
from math import pi
print(pi) # 不用写 math.两种都可以,看场景:
import mathfrom math import pi, sqrt如果想把模块里 所有公开 的名字一次性全部拉进当前命名空间:
from math import *
print(pi)
print(sqrt(16))⚠️ 不推荐这么写。会把一堆名字塞进当前作用域,容易和你自己定义的变量名冲突,代码也变得不清晰。除非交互式探索,正式代码里基本不用。
模块名太长?可以起别名:
import datetime as dt
today = dt.date(2026, 1, 1)
print(today)数据科学圈最常见的两个:
import numpy as np
import pandas as pd.py 文件import 进来的那个类比:你 python a.py,a 就是主模块;a.py 里如果 import b,b 就是非主模块。
__name__ 属性怎么在代码里判断 当前模块到底是被直接运行还是被别人 import 的?
Python 给每个模块都设置了一个特殊变量 __name__:
__name__ 的值就是字符串 '__main__'__name__ 的值就是模块名本身(比如 'mymod')所以经典写法是:
# mymod.py
def main():
print('正在运行 main 逻辑')
if __name__ == '__main__':
main()效果:
python mymod.py → 打印 正在运行 main 逻辑import mymod → 不会自动跑 main(),函数依然可以被调用这是 Python 中最常见的一段「魔法咒语」。它的意义是:写一个模块时,既能让它当库被别人 import,又能让它能直接被运行做测试或当脚本用。
不写 if __name__ == '__main__': 守卫的话,模块里所有顶层代码 都会在被 import 时执行——往往不是你想要的。
# bad_mymod.py
def add(a, b):
return a + b
print(add(1, 2)) # 这一行会在被 import 时立刻执行# 别的文件
import bad_mymod # 副作用:屏幕上立刻打印了 3加上 if __name__ == '__main__': 包裹后,这个 print(add(1, 2)) 就只在直接运行时执行,被 import 时不会触发。
模块多了,难免会出现重名——你写了一个 utils.py,别人也写了一个 utils.py,怎么办?
Python 的解决方案是 包(Package):用 目录 来组织模块,不同目录下可以有同名模块。
一个典型的包结构:
myproject/
└── com/
└── learn/
└── module/
├── __init__.py
└── lname.py ← 完整名是 com.learn.module.lname
注意每个目录里都有一个 __init__.py:
这个文件 必须存在(哪怕是空的),Python 才会把这个目录当成包,而不是普通目录。
__init__.py本身也是一个模块——它对应的模块名就是 包名本身。
导入包里的模块时,用点号一层层进去:
import com.learn.module.lname
from com.learn.module import lname
from com.learn.module.lname import some_func现代 Python(3.3+)也支持 命名空间包——不强制要求
__init__.py。但传统包结构仍然最常见,初学阶段记住「目录里要有__init__.py」就够了。
学过 Java / C++ 的同学知道,类成员可以标 public / private。
Python 没有真正的访问控制关键字,但有一套约定俗成的命名规则:
| 命名 | 含义 | 例子 |
|---|---|---|
abc / MyClass | 公开(public),任何地方都可以用 | 普通函数、变量 |
_abc | 「内部使用」(约定),外部 不应该 直接引用 | 内部辅助函数 |
__abc | 名字改写(name mangling),主要用于类内部 | 类的私有属性 |
__abc__ | 特殊变量 / 魔法方法 | __name__、__init__ |
举例:
def _diamond_vip(lv):
print('尊敬的钻石会员用户,您好')
return f'DiamondVIP{lv}'
def _gold_vip(lv):
print('尊敬的黄金会员用户,您好')
return f'GoldVIP{lv}'
def vip_lv_name(lv):
"""对外公开的入口"""
if lv == 1:
print(_gold_vip(lv))
elif lv == 2:
print(_diamond_vip(lv))
vip_lv_name(2)输出:
尊敬的钻石会员用户,您好
DiamondVIP2
vip_lv_name 是公开的(外部调用入口),_diamond_vip / _gold_vip 名字带下划线——告诉别人「这是我内部用的辅助函数,别去依赖它」。
⚠️ Python 不会真的阻止你访问
_xxx,只是 大家约定 不要这么干。代码就像城市的红绿灯,靠协作而不是栏杆。
下面这几个是日常开发里 超高频 出现的标准库模块,先认识一下,下面几道练习也会用到。
import math
print(math.pi) # 圆周率 3.141592653589793
print(math.e) # 自然常数 e
print(math.sqrt(16)) # 平方根 → 4.0
print(math.floor(3.7)) # 向下取整 → 3
print(math.ceil(3.2)) # 向上取整 → 4import random
random.seed(42) # 固定随机种子,结果可复现
print(random.randint(1, 10)) # 1-10 之间的随机整数(含两端)
print(random.choice(['A', 'B', 'C'])) # 随机选一个在练习里我们会用
random.seed(...)固定结果——这样判分时输出就稳定了。
from datetime import date, datetime
d = date(2026, 1, 1)
print(d.year, d.month, d.day) # 2026 1 1
now = datetime(2026, 1, 1, 12, 30, 0)
print(now) # 2026-01-01 12:30:00把 Python 字典 / 列表 转成 JSON 字符串:
import json
data = {'name': 'Alice', 'age': 18}
print(json.dumps(data))输出:
{"name": "Alice", "age": 18}
反过来——把 JSON 字符串解析回 Python 对象:
import json
s = '{"name": "Alice", "age": 18}'
obj = json.loads(s)
print(obj['name']) # Alice下面来动手练几道。每道题都需要你 使用 import 语句 引入对应的标准库。
读完了?动手练一遍才算真会。
去闯关模式练习 →