系统库
OS标准库(cmd)
OS表示Operating System,即操作系统。OS标准库是一个操作系统接口模块,提供一些方便使用操作系统相关功能的函数,具体安装位置可通过导入os模块查看os.__file__属性得到。当需要在Python代码中调用OS相关功能实现业务逻辑或者无法直接使用命令行工具时,我们就需要考虑导入此模块,因此有必要进行深入学习。
- 文件与目录操作
创建/删除目录:
os.mkdir("new_folder") # 创建单层目录
os.makedirs("a/b/c") # 递归创建多层目录
os.rmdir("new_folder") # 删除空目录
os.removedirs("a/b/c") # 递归删除空目录
文件操作:
os.rename("old.txt", "new.txt") # 重命名文件
os.remove("file.txt") # 删除文件
os.unlink("file.txt") # 同 remove()
- 路径管理(跨平台兼容)
路径拼接与解析:
path = os.path.join("folder", "sub", "file.txt") # 自动处理分隔符(如 folder/sub/file.txt)
dir_name = os.path.dirname(path) # 获取目录名(folder/sub)
file_name = os.path.basename(path) # 获取文件名(file.txt)
路径检查:
os.path.exists("file.txt") # 检查路径是否存在
os.path.isfile("file.txt") # 是否为文件
os.path.isdir("folder") # 是否为目录
os.path.getsize("file.txt") # 获取文件大小(字节)
- 环境变量管理
读取/设置环境变量:
home_dir = os.environ["HOME"] # 读取(Linux/macOS)
os.environ["API_KEY"] = "12345" # 设置临时环境变量(仅在当前进程生效)
获取系统信息:
os.name # 操作系统类型('posix'、'nt'、'java')
os.cpu_count() # 获取 CPU 核心数
sys模块(python解释器)
Python 的 sys 模块是标准库中用于与 Python 解释器及其运行环境交互的核心模块,提供了访问命令行参数、系统配置、程序退出等功能。以下是其核心功能及常见用法:
sys.argv
获取运行 Python 脚本时传递的命令行参数列表
sys.exit([status])
终止 Python 程序,返回状态码(默认 0 表示成功,非 0 表示异常)
sys.path
查看或修改 Python 的模块搜索路径(列表形式)
sys.stdin
标准输入流(默认从键盘读取)
sys.stdout
标准输出流(默认输出到控制台)
sys.stderr
标准错误流(默认输出到控制台)
sys.version
获取 Python 解释器版本信息
sys.platform
获取操作系统标识符(如 win32、linux、darwin)
sys.getdefaultencoding()
获取默认字符串编码(通常为 utf-8)
sys.getfilesystemencoding()
获取文件系统编码(如文件名处理)。
sys.exc_info()
获取当前异常的详细信息(类型、值、回溯栈)。
sys.getsizeof(obj)
返回对象占用的内存字节数(近似值)。
argparse.ArgumentParser模块
Python 的 argparse.ArgumentParser 是标准库中用于解析命令行参数的核心工具,可帮助开发者构建用户友好的命令行接口(CLI)。它支持自动生成帮助文档、参数类型验证、子命令管理等高级功能,是替代 optparse 和手动解析 sys.argv 的现代方案。
- 创建解析器
import argparse
# 初始化解析器(设置程序名称和描述)
parser = argparse.ArgumentParser(
prog="myapp",
description="一个示例程序",
epilog="更多信息见文档"
)
- 添加参数
位置参数(必填)
parser.add_argument("filename", help="输入文件名")
可选参数(以-或–开头)
parser.add_argument("-v", "--verbose", action="store_true", help="启用详细输出")
parser.add_argument("-n", "--number", type=int, default=1, help="重复次数")
- 解析参数
args = parser.parse_args()
print("文件名:", args.filename)
print("详细模式:", args.verbose)
print("重复次数:", args.number)
subprocess模块
Python 的 subprocess 模块是用于创建和管理子进程的标准库工具,它允许你在 Python 程序中执行外部命令、与其他进程交互,并控制输入/输出流。相比旧的 os.system 和 os.popen,subprocess 更灵活且安全,是执行系统命令或调用外部程序的首选方式。
- subprocess.run()
同步执行命令,等待完成并返回结果(推荐用于简单场景)。
import subprocess
result = subprocess.run(
["ls", "-l"], # 命令参数列表(避免使用字符串防注入)
capture_output=True, # 捕获输出
text=True, # 返回字符串而非字节
check=True, # 状态码非零时抛出异常
timeout=10 # 超时时间(秒)
)
print(result.stdout) # 输出命令结果
- subprocess.Popen()
异步执行命令,灵活控制进程(适合复杂场景)。
proc = subprocess.Popen(
["python", "script.py"],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True
)
# 发送输入并等待完成
output, error = proc.communicate(input="数据")
print("输出:", output)
# mpv 调用MPV媒体播放器可执行文件
# --no-cache 禁用缓存,实时播放输入数据(适用于流媒体)
# --no-terminal 不显示终端界面(无头模式运行)
# -- 分隔符,表示后续参数为文件/URL
# fd://0 从标准输入(文件描述符0)读取数据
mpv_command = ["mpv", "--no-cache", "--no-terminal", "--", "fd://0"]
#stdin=subprocess.PIPE 创建输入管道,后续可通过mpv_process.stdin写入数据
#stdout=subprocess.DEVNULL 禁止MPV输出日志到控制台
#stderr=subprocess.DEVNULL 禁止MPV输出错误信息到控制台
mpv_process = subprocess.Popen(
mpv_command,
stdin=subprocess.PIPE,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
- subprocess.check_output()
快速获取命令输出(若失败则抛出异常)。
try:
output = subprocess.check_output(["echo", "Hello"], text=True)
print(output) # "Hello\n"
except subprocess.CalledProcessError as e:
print("命令执行失败:", e)
importlib标准库
Python 的 importlib 模块是标准库中用于动态管理模块导入的工具,它提供了对 Python 导入系统(import system)的底层控制能力。相较于传统的 import 语句,importlib 允许开发者在运行时按需加载模块、重载模块或实现自定义导入逻辑,尤其适合插件化架构、热更新等场景。
- 动态导入模块
import importlib
# 导入模块(等价于 import os)
os_module = importlib.import_module("os")
# 导入子模块(等价于 import pandas.io.json)
json_parser = importlib.import_module("pandas.io.json")
# 相对导入(从当前包导入子模块)
relative_module = importlib.import_module(".submodule", package="mypackage")
- 重载模块(热更新)
import mymodule # 首次导入
importlib.reload(mymodule) # 修改代码后重新加载
- 模块元数据查询
# 检查模块是否存在
spec = importlib.util.find_spec("requests")
if spec is not None:
print("模块存在,路径:", spec.origin)
else:
print("模块不存在")
进程、线程、协程
一个程序可以有10个进程,
一个进程可以有10个线程,
一个线程可以有10个协程。(但没有空余时间,就不要用协程了)
concurrent.futures库
Python 的 concurrent.futures 模块是用于实现多线程/多进程并行编程的高层接口,旨在简化并发任务的执行和管理。它基于线程池(ThreadPoolExecutor)和进程池(ProcessPoolExecutor)的设计模式,提供统一的 API,适用于 I/O 密集型和 CPU 密集型任务的并行处理。
ThreadPoolExecutor
ThreadPoolExecutor通过线程池管理线程,减少了手动管理线程的复杂性,适用于处理大量短期任务。
而threading需要手动创建和管理每个线程,适合需要更精细控制的场景。
run_in_executor()是协程的event_loop自带的
ProcessPoolExecutor
threading标准库
threading 库是用于实现多线程编程的标准库,适合处理 I/O 密集型任务。尽管由于全局解释器锁(GIL)的存在,多线程在 CPU 密集型任务中无法实现真正的并行,但通过线程并发仍能提升效率。
- 适用场景
I/O 密集型任务:如网络请求、文件读写。
并发处理:同时处理多个客户端连接(如 Web 服务器)。
Thread()
- 基本用法
通过 Thread 类创建线程,需指定 target(目标函数)和 args(参数)。线程通过 start() 启动,join() 用于等待线程结束。
import threading
def task(name):
print(f"Thread {name} is running")
#创建线程
t = threading.Thread(target=task, args=("A",))
t.start() # 启动线程
t.join() # 等待线程结束
- 线程同步机制
Lock(互斥锁)
lock = threading.Lock()
counter = 0
def increment():
global counter
with lock: # 自动获取和释放锁
counter += 1
- 守护线程(Daemon Threads)
主线程退出时,守护线程自动终止。适用于后台任务(如心跳检测):
daemon_thread = threading.Thread(target=background_task)
daemon_thread.daemon = True # 设置为守护线程
daemon_thread.start()
- 线程间通信
使用 queue.Queue(线程安全队列)传递数据:
import queue
q = queue.Queue()
def producer():
q.put("Data")
def consumer():
data = q.get()
- 线程局部数据
通过 threading.local() 为每个线程创建独立数据:
thread_local = threading.local()
def set_data(value):
thread_local.value = value # 各线程独立存储
Event()
threading.Event 是 Python 中用于 线程间简单通信 的同步原语,通过一个内部标志位实现多线程的 等待-通知机制。
AsyncIO协程(主要看是不是有IO等待)
asyncio 是 Python 的一个标准库,用于编写单线程并发代码,主要通过协程实现。它在 Python 3.4 版本中引入,提供了基于事件循环的并发模型。
asyncio 的主要特点是事件循环(event loop) 和 协程(coroutine)。
事件循环(event loop)是 asyncio 的核心,可以理解为一个无限循环,我们可以把一些函数(通过 async 定义的函数,称为协程)注册到事件循环(event loop)上,当满足事件发生的条件时,调用相应的协程函数。注意:event loop没有权力收回控制权,只能等await执行完或者函数执行完。
协程(coroutine)是 asyncio 的另一个重要概念,使得我们可以在单线程环境中实现并发操作。它是一种比线程更轻量级的存在,协程(coroutine)的调度完全由用户控制,协程之间的切换不涉及系统调用,开销极小。
使用方式
- run
启动异步程序的主入口,负责创建和管理事件循环。通常用于程序顶层,仅调用一次。
第一步,定义一个coroutine function。
async def:
第二步,coro = fun()
这个fun()是一个coroutine function(有点像是注册的意思),返回的是一个coroutine object,虽然调用了,但是它不会立马运行。
第三步,async.run(coro)
使用async.run(coro)可以启动event loop,并执行coroutine object。
注意:run会立马执行coroutine object,并堵塞
- await
await有点像freertos里面的信号量阻塞,**不过它是单线程的,等完一个再等第二个。**生成器也是同理。
执行await完成了两件事,一是将coroutine转化为task,开始执行task,第二个是告诉event loop你可以开始调度了,我歇会
- gather
gather可以同时把几个coroutine object都放入event loop,并且要等里面所有的coroutine 都完成,才返回event loop给控制权。
协程的Event对象
asyncio.Event() 用于跨协程的事件通知。
核心方法 :
- set() : 设置事件为已触发状态
- clear() : 重置事件为未触发状态
- wait() : 等待事件被触发(协程方法)
协程的Future对象
asyncio.Future() 创建一个新的Future对象。
这个Future永远不会被设置结果(既不会set_result也不会set_exception)。
await 会一直挂起当前协程,直到Future完成(但这里永远不会完成)。
相当于同步代码中的 while True: pass 无限循环
协程的Task对象
Task对象实际是继承Future的类,本身corotine对象是无状态的,封装后的Task能力更强了。
asyncio.create_task()返回一个没有执行的Task对象,使用await等待event_loop调度。
- done()判断协程任务是否完成
- add_done_callback()增加回调函数
- cancel()取消协程任务
- result()获取返回值
queue标准库
Python 的 queue 库(标准库,无需安装)提供了线程安全的队列(FIFO、LIFO、优先级队列)实现,主要用于多线程编程中实现线程间的数据共享和通信。
- 队列类型
queue 模块提供了三种队列:
Queue:先进先出(FIFO)队列。
LifoQueue:后进先出(LIFO)队列(类似栈)。
PriorityQueue:优先级队列,元素按优先级排序(优先级值越小越优先)。
from queue import Queue, LifoQueue, PriorityQueue
#创建队列
fifo_q = Queue(maxsize=3) # 最多容纳3个元素
lifo_q = LifoQueue()
priority_q = PriorityQueue() # 元素格式:(priority, data)
-
核心方法
通用方法
put(item, block=True, timeout=None)
向队列添加元素。若队列满且 block=True,会阻塞直到有空间;若 timeout 超时则抛出 queue.Full 异常。
get(block=True, timeout=None)
从队列取出元素。若队列空且 block=True,会阻塞直到有元素;若 timeout 超时则抛出 queue.Empty 异常。
qsize()
返回队列当前元素数量(注意:此值在多线程环境下可能不精确)。
empty()
判断队列是否为空。
full()
判断队列是否已满。 -
非阻塞方法
put_nowait(item)
等价于 put(item, block=False),队列满时直接抛出 queue.Full。
get_nowait()
等价于 get(block=False),队列空时直接抛出 queue.Empty。 -
任务完成通知
task_done()
标记一个已从队列中获取的任务完成(需与 join() 配合使用)。
join()
阻塞直到队列中所有元素被处理且 task_done() 被调用对应次数。 -
线程安全特性
queue 的队列是线程安全的,内部通过锁机制(threading.Lock)实现,无需手动处理多线程竞争问题。适合在 threading 多线程中共享数据。
IO
BytesIO模块
io.BytesIO 是Python标准库中用于内存二进制流操作的类,提供类似文件对象的接口,但数据存储在内存而非磁盘。
- 核心特点
数据存储在内存而非文件系统
专门处理字节数据(bytes类型)
比磁盘文件操作快10-100倍(实测数据)
程序退出后数据自动消失
- 创建对象
from io import BytesIO
# 创建空缓冲区
bio = BytesIO()
# 创建带初始数据的缓冲区
initial_data = b"Hello World"
bio = BytesIO(initial_data)
- 写入数据
# 写入字节数据
bio.write(b"Binary data example\n")
bio.write(b"\x48\x65\x6C\x6C\x6F") # ASCII码写入:"Hello"
# 当前指针位置
print(bio.tell()) # 输出: 25
- 读取数据
# 重置指针到起始位置
bio.seek(0)
# 读取全部内容
all_data = bio.read()
print(all_data) # b'Hello WorldBinary data example\nHello'
# 分块读取
bio.seek(6)
chunk = bio.read(5)
print(chunk) # b'World'
selectors 模块(IO多路复用)
Python 的 selectors 模块提供了一个高级的 I/O 多路复用接口,它封装了底层的多路复用机制,如 select、poll 和 epoll。这个模块在 Python 3.4 中引入,旨在让程序员更容易地编写高性能的网络应用。
数据处理
pickle库
Python 的 pickle 模块是一个用于对象序列化与反序列化的标准库工具,能够将 Python 对象转换为字节流(序列化)或从字节流恢复对象(反序列化)。它适用于数据持久化、进程间通信等场景,但需注意其安全性和兼容性限制。
序列化(Pickling):将 Python 对象转换为字节流,可保存到文件或网络传输。
反序列化(Unpickling):从字节流重建原始对象,恢复其结构和数据。
- 序列化对象到文件
import pickle
data = {"name": "Alice", "age": 30, "skills": ["Python", "Data"]}
# 写入文件
with open("data.pkl", "wb") as f:
pickle.dump(data, f)
- 从文件反序列化对象
# 读取文件
with open("data.pkl", "rb") as f:
loaded_data = pickle.load(f)
print(loaded_data) # {'name': 'Alice', 'age': 30, 'skills': ['Python', 'Data']}
- 序列化为字节对象(非文件)
# 对象 → 字节流
bytes_data = pickle.dumps(data)
# 字节流 → 对象
restored_data = pickle.loads(bytes_data)
常见问题
-
类定义缺失导致反序列化失败
若序列化的类在反序列化环境中未定义,会抛出 AttributeError。
解决方案:确保反序列化端有相同的类定义。 -
跨 Python 版本兼容性
不同 Python 版本的协议可能不兼容。
解决方案:统一使用低版本协议(如协议 2)或确保环境一致。 -
处理大型对象
序列化大对象可能导致内存问题。
解决方案:分块处理或使用 pickletools 优化。
正则表达式
在 Python 中,正则表达式(Regular Expression,简称 regex 或 regexp)通过内置的 re 模块实现,用于字符串的模式匹配、查找、替换和分割。
- 正则表达式基础语法
- Python re 模块核心方法
匹配对象(MatchObject)
匹配对象(MatchObject)是正则表达式匹配成功后返回的一个对象。
group([group1, group2, …]):返回匹配的子字符串或指定捕获组的内容。
start([group]):返回匹配的子字符串或指定捕获组在原始字符串中的起始索引位置(包含该索引位置的字符)。
end([group]):返回匹配的子字符串或指定捕获组在原始字符串中的结束索引位置(不包含该索引位置的字符)。
span([group]):返回一个元组 (start, end),表示匹配的子字符串或指定捕获组在原始字符串中的起始和结束索引位置。
expand(template):将匹配对象中的捕获组内容插入到模板字符串中。
调试
tqdm进度条
tqdm 是一个用于在 Python 中显示进度条的流行库,其名称源自阿拉伯语 taqaddum(تقدّم),意为“进展”。它简单易用且高度可定制,能够为长时间运行的任务提供实时进度反馈,帮助开发者更直观地监控代码执行状态。
- 在循环中使用
from tqdm import tqdm
import time
# 在 for 循环外包裹 tqdm()
for i in tqdm(range(100)):
time.sleep(0.1) # 模拟耗时操作
- 手动更新(使用with)
with tqdm(total=100) as pbar:
for i in range(10):
time.sleep(0.1)
pbar.update(10) # 手动更新进度(每次增加10%)
- 自定义描述和式样
for i in tqdm(range(100), desc="Processing", ncols=100, bar_format="{l_bar}{bar}| {n_fmt}/{total_fmt}"):
time.sleep(0.1)
- 嵌套进度条
from tqdm import trange
for i in trange(3, desc="Outer"):
for j in trange(5, desc="Inner", leave=False):
time.sleep(0.1)
tracemalloc模块
tracemalloc 是 Python 3.4+ 内置的内存分析工具,用于跟踪内存分配来源,帮助开发者定位内存泄漏和优化内存使用。
- 核心功能
内存分配跟踪 记录每个内存块的分配位置(文件名 + 行号)
内存快照对比 比较不同时间点的内存使用差异
统计信息展示 按文件/行号/大小排序显示内存分配详情
过滤功能 聚焦特定模块或文件的内存分配
内存泄漏检测 识别未释放的内存增长点
- 启用跟踪
import tracemalloc
tracemalloc.start() # 开始跟踪内存分配
# 默认跟踪帧数:1(显示直接调用者),建议设置为 25 获取完整堆栈
# tracemalloc.start(25)
- 创建快照
snapshot1 = tracemalloc.take_snapshot() # 创建初始快照
# ...执行待分析代码...
snapshot2 = tracemalloc.take_snapshot() # 创建后续快照
- 对比分析
top_stats = snapshot2.compare_to(snapshot1, 'lineno') # 按行号对比差异
# 显示前10项内存变化
for stat in top_stats[:10]:
print(stat)