9、Python基础之IO编程
前言IO就是Input/Output输入输出。程序和外部数据交换都属于IO操作读取文件、写入文件、网络传输等。IO操作有一个核心特点速度远慢于CPU计算。 Python内置了丰富的IO支持本篇包含文件读写、StringIO/BytesIO、文件目录操作、序列化。文件读写文件读写是最常见的IO。遵循流程打开文件 → 读写内容 → 关闭文件。open()基础用法# 读取文本文件 f open(test.txt, r, encodingutf-8) content f.read() print(content) f.close()r读文本模式w写文本覆盖原有内容a追加写入encodingutf-8指定文件编码一定要显式指定防止乱码read()一次性读取全部内容大文件不要直接read()容易撑爆内存风险如果中间代码抛出异常close()不会执行文件句柄泄漏。推荐使用with上下文管理器自动关闭文件。# with语句推荐退出代码块自动close with open(test.txt, r, encodingutf-8) as f: print(f.read())按行读取、分块读取# readline() 读一行 with open(test.txt, r, encodingutf-8) as f: line f.readline() print(line) # readlines() 读取所有行返回列表 with open(test.txt, r, encodingutf-8) as f: lines f.readlines() # 直接迭代文件对象最省内存 with open(test.txt, r, encodingutf-8) as f: for line in f: print(line.strip())二进制读写图片、视频、音频都是二进制文件用rb / wb# 读取图片 with open(demo.jpg, rb) as f: data f.read()写文件# w模式覆盖原文件 with open(out.txt, w, encodingutf-8) as f: f.write(Hello IO\n) # a模式追加不会覆盖 with open(out.txt, a, encodingutf-8) as f: f.write(追加一行\n)StringIO 和 BytesIO有时候数据不需要落地到磁盘文件只在内存中读写就用这两个工具在内存里模拟文件。StringIO内存读写字符串from io import StringIO # 写入 f StringIO() f.write(hello) f.write( python) print(f.getvalue()) # 获取全部字符串 # 读取 f2 StringIO(你好\nPython) while True: line f2.readline() if not line: break print(line.strip())BytesIO内存读写bytes字节数据用于二进制比如图片字节、网络二进制流from io import BytesIO f BytesIO() f.write(中文.encode(utf-8)) print(f.getvalue()) # 读取 data b\xe4\xb8\xad\xe6\x96\x87 f2 BytesIO(data) print(f2.read())区别StringIO操作strBytesIO操作bytes。操作文件和目录Python内置os模块调用操作系统接口实现目录创建、删除、遍历、路径拼接。注意os模块的函数很多和操作系统强相关Windows和Linux路径格式不一样不要手动拼接字符串使用os.pathimport os # 当前工作目录 print(os.getcwd()) # 列出指定目录下所有文件和子目录 print(os.listdir(.)) # 判断是否是目录 print(os.path.isdir(./test)) # 判断是否是文件 print(os.path.isfile(test.txt)) # 路径拼接跨平台兼容 p os.path.join(., data, test.txt) print(p) # 创建文件夹 # os.mkdir(./demo) # 删除文件夹 # os.rmdir(./demo) # 删除文件 # os.remove(a.txt)遍历目录下所有文件常用import os def scan_dir(path): for name in os.listdir(path): full_path os.path.join(path, name) if os.path.isdir(full_path): scan_dir(full_path) else: print(full_path) # scan_dir(.)补充Python3.4 推荐 pathlib面向对象路径写法但廖雪峰教程主线用os。序列化把内存中的变量dict、list、对象变成可以存储/传输的字节或者字符串叫序列化反向恢复成内存变量叫反序列化。 Python标准库pickle和json。picklePython专用序列化可以序列化绝大多数Python对象但是只能给Python程序读取跨语言不行。import pickle d {name: 小明, age: 18} # 序列化到bytes b pickle.dumps(d) print(b) # 反序列化 res pickle.loads(b) print(res) # 序列化写入文件 with open(dump.pkl, wb) as f: pickle.dump(d, f) # 从文件读取 with open(dump.pkl, rb) as f: d2 pickle.load(f)json通用JSON序列化工程最常用JSON是跨语言通用格式只能序列化基础类型dict、list、str、int、float、bool、None不能直接序列化自定义类实例。import json d {name: 小明, age: 18} # dict - json字符串 s json.dumps(d, ensure_asciiFalse, indent2) print(s) # json字符串 - dict d2 json.loads(s) print(d2) # 写入文件 with open(data.json, w, encodingutf-8) as f: json.dump(d, f, ensure_asciiFalse, indent2) # 读取文件 with open(data.json, r, encodingutf-8) as f: d3 json.load(f)参数说明ensure_asciiFalse中文正常显示不会转\u编码indent2格式化缩进方便阅读如果要序列化自定义类对象需要自己写转换函数把对象转成dict再dumps。小结文件读写优先with open()自动关闭区分文本模式r/w/a和二进制rb/wb指定utf-8编码StringIO / BytesIO内存文件不需要磁盘IO处理临时字符串、二进制流os模块操作系统目录、文件os.path.join跨平台拼接路径序列化picklePython专属json跨语言通用业务首选。