装好 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才专业。
# ch05-lib/Test01_sys.pyimportsys# 获取命令行参数iflen(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:环境变量字典。
# ch05-lib/Test02_os.pyimportosprint("当前目录:",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)# 检查文件是否存在再写入ifnotos.path.exists(file_path):withopen(file_path,'w')asf: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:请求异常类。
# ch05-lib/Test03_urllib.pyimporturllib.requestimporturllib.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)# 解析 URLparsed=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):从文件读并解析。
# ch05-lib/Test04_json.pyimportjson# 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)# 写入文件withopen("data.json","w",encoding="utf-8")asf:json.dump(data,f,indent=2,ensure_ascii=False)# 从文件读取withopen("data.json","r",encoding="utf-8")asf: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:面向对象,封装了日期、时间、时间间隔。适合做日期加减、格式化输出、解析时间字符串。
# ch05-lib/Test05_time.pyimporttimeprint("时间戳:",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()))# ch05-lib/Test06_datetime.pyfromdatetimeimportdatetime,date,time,timedelta now=datetime.now()print("现在:",now)dt=datetime(2021,4,3,15,30,0)print("指定时间:",dt)tomorrow=now+timedelta(days=1)# 日期加减靠 timedeltaprint("明天:",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、做类型转换、标记必填项,专业命令行工具都靠它。
# ch05-lib/Test07_argparse.pyimportargparse 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}")ifargs.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% 的脚本类需求都能在标准库里解决,不用急着装包。