讲解
一个 .py 文件就是一个模块。代码多了以后,按功能拆进不同模块是组织程序的基本手段。引入模块用 import:import math 之后用 math.sqrt(16) 访问;from math import sqrt, pi 把指定名字直接拿进来,调用时省略前缀;import datetime as dt 给模块起别名。三种形式按场景选:用得杂就 import 模块(前缀让来源清晰),只用一两个名字就 from...import,名字太长就 as 别名。import 语句惯例放在文件顶部,标准库、第三方、自己模块分组排列。
import 一个模块时,模块顶层的代码会被执行一次(之后重复 import 直接拿缓存,不会重新执行)。这引出一个重要惯用法:if name == 'main':。每个模块都有内置变量 name,当文件被直接运行时它是 'main',被 import 时它是模块名。把「只有直接运行才执行」的代码(测试、演示、命令行入口)放进这个 if 里,模块就既能被导入又能被直接运行,互不干扰。
除了标准库模块(import 即用),你还可以 import 自己写的 .py 文件——只要它在同一目录(或在 sys.path 里)。包(package)是含 init.py 的目录,用来组织多个模块,from mypackage.mymodule import func 用点号逐级定位。循环 import(a 导 b、b 导 a)是常见事故,解法是把共享部分抽到第三个模块,或把 import 推迟到函数内。最后别把自己的文件命名成 random.py、json.py 这类标准库同名——你的文件会遮住标准库。
示例
# 三种 import 形式
import math
from random import randint, seed
import datetime as dt
print('import 模块:', math.sqrt(16), math.pi)
seed(42) # 固定随机种子,让输出可复现
print('from...import:', randint(1, 6), randint(1, 6))
print('as 别名:', dt.date(2026, 8, 9).year)
# import 只执行一次:sys.modules 里缓存
import sys
print('math 已缓存:', 'math' in sys.modules)
# __name__:直接运行时是 '__main__'
print('本文件的 __name__:', __name__)
if __name__ == '__main__':
print('这行只在直接运行时打印,被 import 时不会')
# import 标准库的便利功能
from collections import Counter
from pathlib import Path
votes = ['苹果', '香蕉', '苹果', '西瓜', '香蕉', '苹果']
print('一行计票:', Counter(votes).most_common(2))
print('路径拼接:', Path('docs') / 'python' / 'modules.py')
自己写一个 mytools.py 放在同目录,里面定义 def double(x): return x * 2,然后在主文件 import mytools 就能用 mytools.double(21)——动手试试,这是理解模块最好的方式。
常见坑
- 文件名遮住标准库:把自己的文件命名 random.py、email.py、json.py 后 import 同名库会导到自己,报出莫名其妙的错误。文件名避开标准库名字。
- 循环 import:a.py 导 b、b.py 导 a,其中一个会拿到「还没定义完」的半成品模块。把共享代码抽到第三方模块是标准解法。
- **from module import ***:把模块所有公开名字倒进当前命名空间,来源不明、容易撞名,工程代码里禁用。
- 以为多次 import 会重复执行:模块只执行一次并缓存,「改完模块代码没生效」是因为解释器进程没重启,重启即可。
小结
import 模块 / from...import 名字 / as 别名三件套;if name == 'main' 让模块可导入可直接跑;文件名别撞标准库。下一节走出标准库:pip 与第三方包。