装好 Python 就自带一套"官方工具箱"。这篇把最常用的几个标准库过一遍,并把它串成 4 个能直接用的小工具。代码都来自实战片段,路径注释标了出处,照着敲就能跑。
一、为什么要有标准库
Python 装完就自带一大堆功能模块,叫标准库(Standard Library) 。一个模块就是一个 .py 文件,里面是一组相关函数/类,把代码按逻辑拆开,复用性和可维护性都上来了。
它的三个硬优势:
- 零安装 :
import即用,不用pip,部署到哪台机器都不会缺依赖。 - 跨平台 :同一套
os.path.join()在 Windows 和 Linux 上都能正确拼路径,不用自己处理反斜杠。 - 经过毒打:标准库是千万项目磨出来的,稳定性远超你自己手搓的轮子。
判断原则:能用标准库干净解决的,先别急着引第三方库。除非像
urllib(标准库)明显比requests(第三方)啰嗦这种明确场景。
二、sys:和解释器本身对话
WHY :当你想读命令行参数、强制退出程序、临时改模块搜索路径、或重定向标准流时,找 sys。它是你和 Python 解释器之间的后门。
核心成员:
sys.argv:命令行参数列表,argv[0]是脚本名,后面才是真正传进来的参数。sys.exit():主动退出程序(可在参数里带退出信息)。sys.path:模块搜索路径列表,往里append一个路径就能 import 到那里的模块。sys.stdin/sys.stdout/sys.stderr:三个标准流,错误信息走stderr才专业。
python
# ch05-lib/Test01_sys.py
import sys
# 获取命令行参数
if len(sys.argv) > 1:
print(f"脚本名: {sys.argv[0]}")
print(f"第一个参数: {sys.argv[1]}")
else:
print("请提供命令行参数")
# 添加模块路径
sys.path.append('/path/to/my/modules')
# 模块搜索路径
print(sys.path)
# 输出到标准错误
sys.stderr.write("这是一个错误信息\n")
# 退出程序
# sys.exit("程序退出")
命令行跑:python Test01_sys.py a b c,会依次打印脚本名、a,以及拼接后的搜索路径。注意 argv 永远从脚本身开始,取用户输入要从 argv[1] 起。
三、os:跨平台操作文件系统
WHY :文件/目录的增删查改、路径拼接、环境变量读取------凡是跟操作系统打交道的事,别手写字符串路径,交给 os,它在不同系统上自动适配分隔符。
常用方法:
os.getcwd()/os.chdir(path):获取 / 切换当前工作目录。os.listdir(path):列出目录下所有条目。os.makedirs(path, exist_ok=True):递归建多层目录(exist_ok防止重复建报错)。os.path.join():跨平台路径拼接 ,永远用它,别手拼/或\。os.path.exists(path):判存在。os.environ:环境变量字典。
python
# ch05-lib/Test02_os.py
import os
print("当前目录:", os.getcwd())
# 创建目录(exist_ok=True 避免重复运行报错)
os.makedirs("test_dir/sub_dir", exist_ok=True)
# 列出当前目录文件
files = os.listdir(".")
print("文件列表:", files)
# 路径拼接:Windows/Linux 通吃
file_path = os.path.join("test_dir", "sub_dir", "test.txt")
print("完整路径:", file_path)
# 检查文件是否存在再写入
if not os.path.exists(file_path):
with open(file_path, 'w') as f:
f.write("Hello, OS!")
else:
print('文件已存在!')
# 读取环境变量
print("PATH:", os.environ.get("PATH"))
四、urllib:标准库自带的 HTTP 客户端
WHY :不发网络请求也能跑的最小依赖。urllib 能完成 GET/POST、URL 解析,不引第三方包就能联网。真实项目里很多人换 requests(更简洁),但懂 urllib 才看得懂那些老代码和报错。
子模块分工:
urllib.request:打开并读取 URL(发请求)。urllib.parse:拼接 / 解析 URL 参数。urllib.error:请求异常类。
python
# ch05-lib/Test03_urllib.py
import urllib.request
import urllib.parse
# 发送 GET 请求
url = "https://httpbin.org/get"
response = urllib.request.urlopen(url)
data = response.read().decode('utf-8')
print(data)
print('-' * 80)
# 发送 POST 请求(表单编码后用 Request 包装)
data = urllib.parse.urlencode({'key': 'value'}).encode('utf-8')
req = urllib.request.Request("https://httpbin.org/post", data=data)
response = urllib.request.urlopen(req)
print(response.read().decode('utf-8'))
print('-' * 80)
# 解析 URL
parsed = urllib.parse.urlparse("https://example.com:8080/path?query=1")
print(parsed.scheme, parsed.netloc, parsed.path)
小结:
urllib写起来比requests啰嗦(GET 都要urlopen+read+decode三连),但它零依赖。日常开发用requests更爽,面试/读旧代码时urllib跑不掉。
五、json:程序与世界交换数据的通用语
WHY :配置文件、API 响应、前后端通信------JSON 是工业标准。json 模块负责在 Python 对象(dict/list)和 JSON 字符串之间互转。
四个主力方法:
json.dumps(obj):Python 对象 → JSON 字符串。json.loads(s):JSON 字符串 → Python 对象。json.dump(obj, file):直接写进文件。json.load(file):从文件读并解析。
python
# ch05-lib/Test04_json.py
import json
# Python 对象转 JSON 字符串
data = {"name": "Alice", "age": 30, "is_student": False}
json_str = json.dumps(data, indent=2, ensure_ascii=False)
print(json_str)
# JSON 字符串转回 Python 对象
data_back = json.loads(json_str)
print(data_back)
# 写入文件
with open("data.json", "w", encoding="utf-8") as f:
json.dump(data, f, indent=2, ensure_ascii=False)
# 从文件读取
with open("data.json", "r", encoding="utf-8") as f:
loaded_data = json.load(f)
print(loaded_data)
JSON ↔ Python 类型对照表
| JSON | Python |
|---|---|
| object | dict |
| array | list |
| string | str |
| number(int) | int |
| number(real) | float |
| true | True |
| false | False |
| null | None |
两个坑先记着:
dumps默认ensure_ascii=True,中文会被转成\uXXXX,要中文正常显示必须传ensure_ascii=False;dump/load针对文件对象,dumps/loads针对字符串,别混。
六、time 与 datetime:两个时间模块怎么选
WHY:时间处理有两套工具,分工明确------
time:底层、轻量,基于 Unix 时间戳(1970-01-01 起的秒数)。适合简单计时、sleep、时间戳获取。datetime:面向对象,封装了日期、时间、时间间隔。适合做日期加减、格式化输出、解析时间字符串。
python
# ch05-lib/Test05_time.py
import time
print("时间戳:", time.time()) # 当前秒级时间戳
now = time.localtime()
formatted = time.strftime("%Y-%m-%d %H:%M:%S", now) # 格式化为可读字符串
print("格式化时间:", formatted)
t = time.strptime("2021-04-03 10:00:00", "%Y-%m-%d %H:%M:%S") # 解析回去
print("解析后时间结构:", t)
print(time.strftime('%H:%M:%S', time.localtime()))
print("暂停 2 秒...")
time.sleep(2) # 阻塞当前线程
print(time.strftime('%H:%M:%S', time.localtime()))
python
# ch05-lib/Test06_datetime.py
from datetime import datetime, date, time, timedelta
now = datetime.now()
print("现在:", now)
dt = datetime(2021, 4, 3, 15, 30, 0)
print("指定时间:", dt)
tomorrow = now + timedelta(days=1) # 日期加减靠 timedelta
print("明天:", tomorrow)
print("格式化:", now.strftime("%Y年%m月%d日 %H:%M:%S"))
parsed_dt = datetime.strptime("2021-04-03 15:40:00", "%Y-%m-%d %H:%M:%S")
print("解析时间:", parsed_dt)
print("今天:", date.today())
选择口诀:要算"差了几天/几小时"用
datetime.timedelta;要打时间戳、计个时、睡两秒用time。
七、argparse:把命令行参数管起来
WHY :手动解析 sys.argv 容易漏边界、难校验类型。argparse 自动生成 --help、做类型转换、标记必填项,专业命令行工具都靠它。
python
# ch05-lib/Test07_argparse.py
import argparse
parser = argparse.ArgumentParser(description="一个示例程序")
parser.add_argument('--name', type=str, required=True, help='你的名字')
parser.add_argument('--age', type=int, default=18, help='年龄')
parser.add_argument('--verbose', action='store_true', help='详细模式')
parser.add_argument('filename', help='文件名') # 位置参数,无 -- 前缀
args = parser.parse_args()
print(f"名字: {args.name}")
print(f"年龄: {args.age}")
print(f"文件名: {args.filename}")
if args.verbose:
print("详细模式已开启")
命令行:python Test07_argparse.py info.txt --name lao8 --age 18 --verbose。注意 filename 是位置参数(直接跟在后面),--name/--age 是可选参数,--verbose 是开关(store_true,出现即为 True)。缺了 required=True 的 --name,argparse 会直接报错退出并打印用法。
小结:标准库是 Python 自带的生产力工具箱------
sys管解释器、os管文件系统、urllib管网络、json管数据交换、time/datetime管时间、argparse管命令行。记住三条:路径永远用os.path.join;JSON 中文必带ensure_ascii=False;命令行参数优先用argparse而非手撕sys.argv。把这套用熟,80% 的脚本类需求都能在标准库里解决,不用急着装包。