

大家好,我是正在实战各种AI项目的程序员晚枫。
你有没有这样的经历?写了一半代码突然发现——要操作文件,os模块怎么写来着?要处理日期,datetime又要查文档?要解析JSON,到底用json.load还是json.loads?
说实话,我刚开始学Python的时候,每次用到标准库都要翻文档,效率低得要命。后来我强迫自己把这10个最常用的标准库全部吃透,现在写代码行云流水,再也不用来回查了。
上篇我们学习了函数。今天来介绍Python标准库——这是Python自带的"工具箱",不用安装,导入就能用。
我每天工作至少用10个标准库。学会它们,你的开发效率会大幅提升。
为什么学标准库?
想象你搬家,需要:
- 打包箱子(os)
- 查日历算日期(datetime)
- 随机抽签决定谁搬重物(random)
- 读写合同文件(json)
如果这些都要自己造轮子,会累死。好消息是:Python已经帮你造好了这些轮子,直接用!
标准库 vs 第三方库,区别在哪?
很多同学搞不清楚标准库和第三方库的区别,这里说清楚:
| 对比项 | 标准库 | 第三方库 |
|---|
| 安装方式 | Python自带,无需安装 | 需要pip install |
| 示例 | os, json, datetime | requests, pandas, flask |
| 稳定性 | Python官方维护,非常稳定 | 社区维护,版本变化大 |
| 兼容性 | 随Python版本走 | 可能有不兼容问题 |
💡 我的建议:能用标准库解决的就别装第三方库。少一个依赖,少一个坑。
1. os - 操作系统接口
管文件、管目录,样样精通。这是我用得最多的标准库,没有之一。
场景:看看今天下载文件夹里有什么
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import os
print(os.getcwd())
files = os.listdir(".") print("当前目录的文件:") for f in files: print(f" - {f}")
os.mkdir("test_folder")
print(os.path.exists("test_folder")) print(os.path.isfile("test.py")) print(os.path.isdir("test_folder"))
|
运行结果:
1 2 3 4 5 6 7 8 9
| C:\Users\admin\project 当前目录的文件: - test.py - main.py - README.md - test_folder True False True
|
进阶用法:环境变量和路径拼接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import os
home = os.environ.get('HOME') userprofile = os.environ.get('USERPROFILE') print(f"用户目录:{home or userprofile}")
config_path = os.path.join(home, '.config', 'myapp', 'settings.json') print(f"配置文件路径:{config_path}")
filepath = "/home/user/docs/report.pdf" print(f"文件名:{os.path.basename(filepath)}") print(f"目录名:{os.path.dirname(filepath)}") print(f"文件名+扩展名:{os.path.splitext('report.pdf')}")
for root, dirs, files in os.walk("."): for f in files: print(os.path.join(root, f))
|
避坑指南
1 2 3 4 5 6 7 8 9 10 11 12 13
| import os
path = home + "/Downloads/test.txt"
path = os.path.join(home, "Downloads", "test.txt")
os.mkdir("a/b/c")
os.makedirs("a/b/c", exist_ok=True)
|
2. datetime - 日期和时间
处理日期、时间、算天数差。做报表、做定时任务都离不开它。
场景:距离过年还有多少天?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| from datetime import datetime, timedelta
now = datetime.now() print(f"现在是:{now}")
print(now.strftime("%Y年%m月%d日 %H:%M:%S"))
target = datetime(2027, 1, 29) delta = target - now print(f"距离过年还有 {delta.days} 天")
tomorrow = now + timedelta(days=1) last_week = now - timedelta(weeks=1) print(f"明天是:{tomorrow.strftime('%Y-%m-%d')}")
|
运行结果:
1 2 3 4
| 现在是:2026-04-16 14:45:00.123456 2026年04月16日 14:45:00 距离过年还有 288 天 明天是:2026-04-17
|
进阶用法:字符串和日期互转
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| from datetime import datetime
date_str = "2026-04-16" dt = datetime.strptime(date_str, "%Y-%m-%d") print(f"解析结果:{dt},类型:{type(dt)}")
formatted = dt.strftime("%Y年%m月%d日 星期%w") print(f"格式化后:{formatted}")
print(datetime.now().strftime("%Y-%m-%d %H:%M:%S")) print(datetime.now().strftime("%Y/%m/%d")) print(datetime.now().strftime("%B %d, %Y"))
|
实战:计算工作日天数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| from datetime import datetime, timedelta
def count_workdays(start_date, end_date): """计算两个日期之间的工作日天数""" workdays = 0 current = start_date while current <= end_date: if current.weekday() < 5: workdays += 1 current += timedelta(days=1) return workdays
start = datetime(2026, 4, 1) end = datetime(2026, 4, 30) print(f"4月工作日:{count_workdays(start, end)}天")
|
避坑指南
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| from datetime import datetime
"2026-04-16" > "2026-04-15"
datetime(2026, 4, 16) > datetime(2026, 4, 15)
from datetime import timezone utc_now = datetime.now(timezone.utc) print(f"UTC时间:{utc_now}")
|
3. json - 数据处理
存数据、读数据,JSON是互联网通用格式。做配置文件、API接口、数据存储都离不开它。
场景:保存和读取用户配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import json
user_config = { "username": "张三", "theme": "dark", "notifications": True, "languages": ["Python", "JavaScript"] }
with open("config.json", "w", encoding="utf-8") as f: json.dump(user_config, f, ensure_ascii=False, indent=2)
with open("config.json", "r", encoding="utf-8") as f: loaded = json.load(f)
print(f"用户名:{loaded['username']}") print(f"主题:{loaded['theme']}")
|
运行结果:
💡 小技巧:indent=2 让JSON格式化后好看,ensure_ascii=False 让中文正常显示。
进阶用法:字符串和JSON互转
1 2 3 4 5 6 7 8 9 10 11
| import json
json_str = '{"name": "晚枫", "skills": ["Python", "AI"]}' data = json.loads(json_str) print(f"名字:{data['name']},技能:{data['skills']}")
person = {"name": "晚枫", "age": 30, "is_dev": True} json_text = json.dumps(person, ensure_ascii=False, indent=2) print(json_text)
|
load vs loads,dump vs dumps——别再搞混了!
| 函数 | 作用 | 记忆方法 |
|---|
json.load(f) | 从文件读取JSON | load = 从文件加载 |
json.loads(s) | 从字符串读取JSON | s = string |
json.dump(obj, f) | 写入文件 | dump = 倒入文件 |
json.dumps(obj) | 转成字符串 | s = string |
避坑指南
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| import json
data = {"tags": {1, 2, 3}} json.dumps(data)
data = {"tags": list({1, 2, 3})}
with open("data.json", "w") as f: json.dump(data, f)
with open("data.json", "w", encoding="utf-8") as f: json.dump(data, f, ensure_ascii=False, indent=2)
with open("data.json") as f: data = json.load(f)
try: with open("data.json", encoding="utf-8") as f: data = json.load(f) except json.JSONDecodeError as e: print(f"JSON解析失败:{e}") except FileNotFoundError: print("配置文件不存在,使用默认配置") data = {}
|
4. random - 随机数
抽奖、摇号、模拟测试,随机数用处大。
场景:年会抽奖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import random
employees = ["张三", "李四", "王五", "赵六", "钱七", "孙八"]
lucky = random.choice(employees) print(f"幸运员工:{lucky}")
winners = random.sample(employees, 3) print(f"中奖的3位:{winners}")
order = employees.copy() random.shuffle(order) print(f"抽签顺序:{order}")
dice = random.randint(1, 6) print(f"掷出的点数:{dice}")
|
运行结果(每次不同):
1 2 3 4
| 幸运员工:王五 中奖的3位:['钱七', '张三', '孙八'] 抽签顺序:['赵六', '钱七', '王五', '张三', '孙八', '李四'] 掷出的点数:4
|
进阶用法:随机数生成和种子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import random
print(random.random())
print(random.uniform(10, 20))
prizes = ["一等奖", "二等奖", "谢谢参与"] weights = [1, 5, 94] result = random.choices(prizes, weights=weights, k=5) print(f"抽奖结果:{result}")
random.seed(42) print(random.randint(1, 100)) random.seed(42) print(random.randint(1, 100))
|
避坑指南
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| import random
token = str(random.random())
import secrets token = secrets.token_hex(16) print(f"安全Token:{token}")
random.sample([1, 2, 3], 5)
data = [1, 2, 3] k = min(5, len(data)) result = random.sample(data, k)
employees = ["张三", "李四", "王五"] random.shuffle(employees)
order = employees.copy() random.shuffle(order)
|
5. sys - 系统相关
查看Python版本、退出程序、修改模块路径。写命令行工具时必备。
查看Python环境
1 2 3 4 5 6
| import sys
print(f"Python版本:{sys.version}") print(f"当前平台:{sys.platform}") print(f"命令行参数:{sys.argv}") print(f"模块搜索路径数量:{len(sys.path)}")
|
运行结果:
1 2 3 4
| Python版本:3.11.1 (tags/v3.11.1:a0e29fc, Jan 15 2024, 11:53:16) [MSC v.1928 64 bit (AMD64)] 当前平台:win32 命令行参数:['app.py'] 模块搜索路径数量:45
|
进阶用法:命令行参数处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import sys
if len(sys.argv) < 2: print("用法:python script.py <文件名>") sys.exit(1)
filename = sys.argv[1] print(f"处理文件:{filename}")
import time for i in range(100): sys.stdout.write(f"\r进度:{i+1}%") sys.stdout.flush() time.sleep(0.05) print("\n完成!")
|
实战:简单的命令行工具
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| import sys
def main(): """一个简单的文件统计工具""" if len(sys.argv) < 2: print("用法:python wordcount.py <文件名>") sys.exit(1) filename = sys.argv[1] try: with open(filename, 'r', encoding='utf-8') as f: content = f.read() chars = len(content) words = len(content.split()) lines = content.count('\n') + 1 print(f"文件:{filename}") print(f"行数:{lines}") print(f"词数:{words}") print(f"字符数:{chars}") except FileNotFoundError: print(f"文件不存在:{filename}") sys.exit(1)
if __name__ == "__main__": main()
|
6. pathlib - 路径操作(推荐用这个)
比os.path更优雅的路径处理方式。Python 3.4+推荐使用,代码可读性大幅提升。
场景:批量处理文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| from pathlib import Path
home = Path.home() downloads = home / "Downloads"
pics = list(downloads.glob("*.jpg")) + list(downloads.glob("*.png")) print(f"下载文件夹里有 {len(pics)} 张图片")
new_folder = downloads / "整理" / "图片" new_folder.mkdir(parents=True, exist_ok=True) print(f"已创建:{new_folder}")
readme = Path("README.md") print(f"README.md 存在吗?{readme.exists()}") print(f"文件大小:{readme.stat().st_size} 字节")
|
运行结果:
1 2 3 4
| 下载文件夹里有 23 张图片 已创建:C:\Users\admin\Downloads\整理\图片 README.md 存在吗?True 文件大小:1523 字节
|
pathlib vs os.path 写法对比
1 2 3 4 5 6 7 8 9 10 11 12
| import os from pathlib import Path
p = Path.home() / "Downloads" / "report.pdf" print(p.stem) print(p.suffix) print(p.parent)
p = os.path.join(os.path.expanduser("~"), "Downloads", "report.pdf") print(os.path.splitext(os.path.basename(p))[0])
|
💡 结论:功能一样,但pathlib代码更清晰。新项目推荐用pathlib!
进阶用法:glob模式匹配
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| from pathlib import Path
py_files = list(Path(".").rglob("*.py")) print(f"当前目录下有 {len(py_files)} 个Python文件")
sorted_files = sorted(py_files, key=lambda f: f.stat().st_mtime, reverse=True) print("最近修改的5个文件:") for f in sorted_files[:5]: print(f" {f.name} ({f.stat().st_size} bytes)")
config = Path("config.txt") config.write_text("debug=True\n", encoding="utf-8") content = config.read_text(encoding="utf-8") print(f"配置内容:{content}")
|
7. collections - 特殊数据结构
一些有用的数据结构工具。用好了能让代码更简洁、更高效。
场景:统计词频
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| from collections import Counter
text = "python java python go python rust java python"
words = text.split() counter = Counter(words)
print("词频统计:") for word, count in counter.most_common(): print(f" {word}: {count}次")
print(f"\n最常见的2个:{counter.most_common(2)}")
|
运行结果:
1 2 3 4 5 6 7
| 词频统计: python: 4次 java: 2次 go: 1次 rust: 1次
最常见的2个:[('python', 4), ('java', 2)]
|
进阶用法:defaultdict和namedtuple
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| from collections import defaultdict, namedtuple
word_count = defaultdict(int) for word in ["python", "java", "python", "go"]: word_count[word] += 1 print(dict(word_count))
names = ["Alice", "Anna", "Bob", "Charlie", "Cathy"] groups = defaultdict(list) for name in names: groups[name[0]].append(name) print(dict(groups))
Point = namedtuple('Point', ['x', 'y']) p = Point(3, 4) print(f"坐标:({p.x}, {p.y}),距离原点:{(p.x**2 + p.y**2)**0.5}")
Student = namedtuple('Student', ['name', 'age', 'score']) students = [ Student("张三", 20, 85), Student("李四", 21, 92), Student("王五", 19, 78), ] top_student = max(students, key=lambda s: s.score) print(f"最高分:{top_student.name},分数:{top_student.score}")
|
8. re - 正则表达式
文本处理的瑞士军刀。提取、替换、验证,一个正则搞定。
场景:从文本中提取手机号
1 2 3 4 5 6 7 8 9 10 11 12 13
| import re
text = "我的手机是13800138000,还有18512345678,紧急联系13999999999"
phones = re.findall(r'1[3-9]\d{9}', text) print(f"找到的手机号:{phones}")
email = "user@example.com" pattern = r'^[\w.-]+@[\w.-]+\.\w+$' is_valid = bool(re.match(pattern, email)) print(f"{email} 是有效邮箱吗?{is_valid}")
|
运行结果:
1 2
| 找到的手机号:['13800138000', '18512345678', '13999999999'] user@example.com 是有效邮箱吗?True
|
进阶用法:替换和分组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import re
text = "联系电话:13812345678,备用:18687654321" masked = re.sub(r'(\d{3})\d{4}(\d{4})', r'\1****\2', text) print(f"脱敏后:{masked}")
log = '2026-04-16 14:30:00 [ERROR] Connection timeout' pattern = r'(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2}) \[(\w+)\] (.+)' match = re.match(pattern, log) if match: date, time, level, msg = match.groups() print(f"日期:{date},时间:{time},级别:{level},信息:{msg}")
html = "<p>这是<b>重要</b>的内容</p>" clean = re.sub(r'<[^>]+>', '', html) print(f"清理后:{clean}")
|
避坑指南
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import re
text = "<div>第一段</div><div>第二段</div>" result = re.findall(r'<div>.*</div>', text) print(result)
result = re.findall(r'<div>.*?</div>', text) print(result)
pattern = re.compile(r""" \d{4} # 年份 - # 分隔符 \d{2} # 月份 - # 分隔符 \d{2} # 日期 """, re.VERBOSE)
|
9. math - 数学运算
开方、绝对值、三角函数等。科学计算、游戏开发都用得到。
场景:计算圆面积和两点距离
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| import math
radius = 5 area = math.pi * radius ** 2 print(f"半径{radius}的圆,面积:{area:.2f}")
x1, y1 = 0, 0 x2, y2 = 3, 4 distance = math.sqrt((x2-x1)**2 + (y2-y1)**2) print(f"点(0,0)到点(3,4)的距离:{distance}")
print(f"向上取整 4.3 = {math.ceil(4.3)}") print(f"向下取整 4.7 = {math.floor(4.7)}")
|
运行结果:
1 2 3 4
| 半径5的圆,面积:78.54 点(0,0)到点(3,4)的距离:5.0 向上取整 4.3 = 5 向下取整 4.7 = 4
|
进阶用法:角度弧度和对数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import math
angle_deg = 90 angle_rad = math.radians(angle_deg) print(f"90度 = {angle_rad:.4f}弧度")
print(f"sin(90°) = {math.sin(angle_rad):.4f}") print(f"cos(90°) = {math.cos(angle_rad):.6f}")
print(f"ln(e) = {math.log(math.e):.4f}") print(f"log2(8) = {math.log2(8)}") print(f"log10(100) = {math.log10(100)}")
print(f"gcd(12, 8) = {math.gcd(12, 8)}") print(f"5! = {math.factorial(5)}")
|
避坑:math vs cmath
1 2 3 4 5 6 7 8 9
| import math
import cmath result = cmath.sqrt(-1) print(f"√(-1) = {result}")
|
生成排列、组合、无限序列。处理大数据时特别省内存。
场景:生成密码字典
1 2 3 4 5 6 7 8 9
| import itertools
codes = itertools.product('01', repeat=4) for i, code in enumerate(codes): print(''.join(code), end=' ') if i >= 10: print('...') break
|
运行结果:
1
| 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 ...
|
进阶用法:排列组合和分组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import itertools
people = ['A', 'B', 'C'] perms = list(itertools.permutations(people, 2)) print(f"排列数:{len(perms)},结果:{perms}")
combs = list(itertools.combinations(people, 2)) print(f"组合数:{len(combs)},结果:{combs}")
data = range(10) groups = list(itertools.batched(data, 3)) print(f"分组结果:{groups}")
list1 = [1, 2] list2 = ['a', 'b'] chained = list(itertools.chain(list1, list2)) print(f"链接后:{chained}")
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| import itertools import time
start = time.time() squares = [x**2 for x in range(1000000)] print(f"列表推导耗时:{time.time()-start:.3f}s,内存:约{len(squares)*8/1024/1024:.1f}MB")
start = time.time() square_iter = (x**2 for x in range(1000000)) print(f"生成器耗时:{time.time()-start:.3f}s,内存:约0MB")
|
💡 结论:数据量大时,用迭代器比列表省内存。100万条数据,列表占几十MB,迭代器几乎为0。
🔥 实战案例:用标准库写一个日志分析工具
把上面学的标准库串起来,写一个实用的小工具:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| import re import json from pathlib import Path from collections import Counter from datetime import datetime
def analyze_log(log_path): """分析日志文件,统计错误和访问趋势""" log_file = Path(log_path) if not log_file.exists(): print(f"文件不存在:{log_path}") return error_counter = Counter() hourly_counter = Counter() total_lines = 0 error_lines = 0 for line in log_file.read_text(encoding='utf-8').splitlines(): total_lines += 1 time_match = re.search(r'(\d{2}):\d{2}:\d{2}', line) if time_match: hour = time_match.group(1) hourly_counter[hour] += 1 level_match = re.search(r'\[(ERROR|WARN|INFO)\]', line) if level_match: level = level_match.group(1) if level == 'ERROR': error_lines += 1 msg_match = re.search(r'\[ERROR\] (.+)', line) if msg_match: error_counter[msg_match.group(1)[:50]] += 1 print("\n" + "="*50) print(f"📊 日志分析报告") print(f"文件:{log_file.name}") print(f"总行数:{total_lines}") print(f"错误行数:{error_lines}") if total_lines > 0: print(f"错误率:{error_lines/total_lines*100:.1f}%") print(f"\n🔴 Top 5 错误:") for msg, count in error_counter.most_common(5): print(f" [{count}次] {msg}") print(f"\n📈 每小时访问量:") for hour in sorted(hourly_counter.keys()): bar = '█' * (hourly_counter[hour] // 10) print(f" {hour}:00 {bar} ({hourly_counter[hour]})") print("="*50) report = { "file": log_file.name, "total_lines": total_lines, "error_lines": error_lines, "top_errors": error_counter.most_common(5), "hourly_stats": dict(hourly_counter) } report_path = log_file.with_suffix('.report.json') report_path.write_text( json.dumps(report, ensure_ascii=False, indent=2), encoding='utf-8' ) print(f"\n报告已保存:{report_path}")
analyze_log('app.log')
|
这个实战案例一口气用到了5个标准库:re解析日志、Counter统计词频、Path操作文件、json保存报告、datetime处理时间。这就是标准库的威力——不用装任何第三方包,就能做出实用工具!
📚 推荐:Python 零基础实战营
系统学习Python,推荐这个免费入门课程 👇
| 特点 | 说明 |
|---|
| 🎯 专为0基础设计 | 门槛低,上手快 |
| 📹 配套视频讲解 | 配合文章学习效果更好 |
| 💬 专属答疑群 | 遇到问题有人带 |
| 🎁 实体书赠送 | 优秀学员送《Python编程从入门到实践》 |
👉 点击免费领取 Python 零基础实战营
本讲小结
| 模块 | 用途 | 常用函数 |
|---|
os | 文件/目录操作 | listdir, mkdir, path.exists, environ |
datetime | 日期时间 | now, strftime, strptime, timedelta |
json | 数据格式转换 | dump, load, dumps, loads |
random | 随机数 | choice, sample, randint, choices, seed |
pathlib | 路径操作 | glob, rglob, mkdir, stat, read_text |
collections | 特殊数据结构 | Counter, defaultdict, namedtuple |
re | 正则表达式 | findall, match, sub, search |
math | 数学运算 | sqrt, pi, ceil, floor, gcd, log2 |
itertools | 迭代器工具 | product, permutations, combinations, chain |
sys | 系统相关 | argv, exit, version, platform |
下节预告
标准库学完了,下一篇开始实战项目,把学到的知识用起来!
👉 继续阅读:Python实战项目-自动整理下载文件夹
课程导航
上一篇: Python函数基础
下一篇: Python实战项目-自动整理下载文件夹
PS:标准库是Python自带的"百宝箱"。用好了这些工具,效率翻倍!
🎓 AI 编程实战课程
想系统学习 AI 编程?程序员晚枫的 AI 编程实战课 帮你从零上手!