news 2026/10/10 4:41:46

Python之os模块案例详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python之os模块案例详解

前言


os模块是 Python 与操作系统打交道的入口:路径、目录、环境变量、进程信息、文件描述符,都从它这里走。它的特点是函数名短、参数少、但语义差异大——os.remove和os.rmdir只差几个字母,一个删文件一个删空目录,用错就是一句报错甚至误删。


几个常见误解:以为os.listdir()返回排序后的结果(不保证);以为os.walk()的dirnames可以直接拿来当完整路径用(不行,需要os.path.join);以为os.environ改了就写回系统了(只改当前进程)。


本文用「路径与环境 → 目录遍历 → 进程与系统信息」三个板块,把os模块最常用的部分配上可直接运行的示例讲清楚。示例面向 Python 3.8+。


一、路径、分隔符与环境变量


先说几个常量和函数,它们让代码能跨平台:




名称含义典型值



os.name操作系统大类'posix'、'nt'

os.sep路径分隔符'/'或'\\'

os.pathsepPATH 里的分隔符':'或';'

os.linesep行分隔符'\n'或'\r\n'



os.getcwd()返回当前工作目录,os.chdir(path)切换:


# 适用于 Python 3.8+
import os

print(os.getcwd())
os.chdir("..") # 切到上级目录
print(os.getcwd())

注意os.getcwd()拿到的和脚本文件所在目录不是一回事。从别处执行脚本时,工作目录是「你在哪敲的命令」,不是「脚本放在哪」。要拿脚本自身的目录,得用__file__推算。


环境变量通过os.environ这个映射对象访问:


# 适用于 Python 3.8+
import os

home = os.environ.get("HOME") or os.environ.get("USERPROFILE")
print(home)

os.environ["APP_MODE"] = "debug" # 只影响当前进程及其子进程

os.environ[key]在键不存在时抛KeyError,所以一般用os.environ.get(key, default)或os.getenv(key, default)。两者差别不大:os.getenv就是os.environ.get的薄封装。


二、目录遍历:listdir、scandir、walk


os.listdir(path='.')返回目录下所有条目名的列表,不含'.'和'..',也不保证顺序。它返回的是名字,不是路径,要拼完整路径得自己os.path.join:


# 适用于 Python 3.8+
import os

for name in os.listdir("."):
full = os.path.join(".", name)
print(full, os.path.isdir(full))

上面这段代码对每个条目都要额外调一次os.path.isdir,也就是一次系统调用。


os.scandir(path='.')返回的是os.DirEntry迭代器,每个entry自带name、path属性和is_file()/is_dir()/stat()方法,这些信息在扫描目录时往往一并拿到了,所以能少掉大量额外调用。它同时是上下文管理器:


# 适用于 Python 3.8+
import os

with os.scandir(".") as it:
for entry in it:
if entry.is_file() and not entry.name.startswith("."):
print(entry.name)

官方文档特别提醒:os.DirEntry不适合长期保存,因为它的缓存会过期,需要最新信息时应改用os.stat(entry.path)。


os.walk(top, topdown=True, onerror=None, followlinks=False)是最常用的递归遍历工具。它对树里每个目录产出一个三元组(dirpath, dirnames, filenames):


# 适用于 Python 3.8+
import os
from os.path import join, getsize

for root, dirs, files in os.walk("project"):
print(root, "里", len(files), "个文件")
total = sum(getsize(join(root, name)) for name in files)
print(" 合计", total, "字节")
if "__pycache__" in dirs:
dirs.remove("__pycache__") # 原地裁剪,跳过该子树

三件事必须记住:dirnames和filenames里都只是名字,不含路径;topdown=True时原地修改dirnames可以剪枝(topdown=False时改了没用);列表是否有序取决于文件系统,官方明确不保证。


三、进程与系统信息


os里还有一批读取进程/系统状态的小工具,写脚本时很有用:


# 适用于 Python 3.8+
import os

print("进程号", os.getpid())
print("父进程号", os.getppid())
print("CPU 核心数", os.cpu_count())

os.cpu_count()返回逻辑 CPU 数量,在无法确定的平台上返回None,拿它做多进程进程池大小时要判空。CPU 密集任务用multiprocessing才能真正并行;os.cpu_count()常常就是进程数的起点。


创建目录用os.mkdir和os.makedirs:


# 适用于 Python 3.8+
import os

os.mkdir("out") # 只建一层,父目录不存在会失败
os.makedirs("a/b/c", exist_ok=True) # 逐级创建,exist_ok=True 时已存在不报错

实战:统计目录树里各类文件的数量与体积


下面这段脚本把walk、路径判断和stat组合起来,输出扩展名分布:


# 适用于 Python 3.8+
import os
from collections import defaultdict

def summarize(top):
total = defaultdict(lambda: [0, 0]) # 扩展名 -> [个数, 字节数]
for root, dirs, files in os.walk(top):
dirs[:] = [d for d in dirs if not d.startswith(".")] # 剪掉隐藏目录
for name in files:
full = os.path.join(root, name)
ext = os.path.splitext(name)[1].lower() or "(无扩展名)"
try:
size = os.path.getsize(full)
except OSError:
continue # 断链、权限不足等,跳过
stat = total[ext]
stat[0] += 1
stat[1] += size
return total

if __name__ == "__main__":
for ext, (count, size) in sorted(summarize(".").items(),
key=lambda kv: -kv[1][1]):
print(f"{ext:<12} {count:>6} 个 {size:>12} 字节")

这里用dirs[:] = [...]做切片赋值,是因为os.walk依赖原地修改dirnames列表对象来判断是否继续递归;直接dirs = [...]只是把局部名字重新绑定,walk看不到,剪枝就失效了。


常见坑点


1. 以为listdir返回有序结果


❌os.listdir(".")[0]当「第一个文件」用,不同文件系统结果不同。 ✅ 需要顺序就自己排:sorted(os.listdir("."))。


2. 把walk的filenames当完整路径


❌open(name)直接打开,报文件找不到。 ✅open(os.path.join(root, name))。


3. 剪枝时重新绑定而不是原地改


❌dirs = [d for d in dirs if ...],os.walk根本看不到。 ✅dirs[:] = [d for d in dirs if ...],切片赋值改的是同一个列表。


4.os.environ[key]取不存在的键


❌os.environ["PATHX"]抛KeyError。 ✅os.getenv("PATHX", "")或os.environ.get("PATHX", "")。


5. 把getcwd()当成脚本目录


❌ 用os.getcwd()拼资源路径,换个目录执行就找不到文件。 ✅ 用os.path.dirname(os.path.abspath(__file__))定位脚本自身目录。


6.os.makedirs不带exist_ok


❌ 重复执行脚本时FileExistsError直接中断。 ✅os.makedirs(path, exist_ok=True)。


7.os.cpu_count()返回None时直接用


❌Pool(os.cpu_count())在拿不到核心数的平台上会出错。 ✅os.cpu_count() or 1,给一个安全兜底。


8. 用os.remove删目录


❌os.remove("somedir"),抛IsADirectoryError(POSIX 上)或PermissionError(Windows 上)。 ✅ 删空目录用os.rmdir,删整树用shutil.rmtree。


总结




需求函数关键点



当前目录os.getcwd()是「执行位置」,不是脚本位置

列目录名os.listdir(path='.')无序、只有名字

带类型扫描os.scandir(path='.')DirEntry,信息缓存会过期

递归遍历os.walk(top, ...)dirnames原地改可剪枝

读环境变量os.getenv(key, default)不存在返回默认值

建目录os.makedirs(name, exist_ok=True)逐级创建

系统信息os.cpu_count()可能返回None



os模块本身不难,难在「返回的是名字还是路径」「顺序有没有保证」「列表改的是对象还是名字」这三类细节上。把os.path.join用熟、把dirs[:]记住,绝大多数问题都能避开。




版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/10 4:41:42

C++ 实现 Web 自动化测试:从 WebDriver 协议到可落地封装

C 写 Web 自动化测试&#xff1f;听到这个选题&#xff0c;不少人第一反应是&#xff1a;你是不是拿错键盘了。网上搜自动化测试&#xff0c;十个教程八个在讲 Python&#xff0c;剩下两个在讲 Java。但我在真实项目里确实遇到过这个需求&#xff0c;而且是那种绕不开的情况——…

作者头像 李华
网站建设 2026/10/10 4:41:04

MCU接管PCA9422电源管理:I2C配置与状态机实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/10 4:40:56

WorkBuddy集成Space-Bunny:企业级匿名AI推理实践指南

1. 项目概述&#xff1a;WorkBuddy Space-Bunny 这次联动到底在解决什么问题&#xff1f;“腾讯 WorkBuddy 独家接入匿名模型 Space-Bunny&#xff0c;限时折扣至 10 月 7 日”——这个标题乍看像一则促销广告&#xff0c;但如果你在企业级AI工具链、研发提效或合规敏感型团队…

作者头像 李华
网站建设 2026/10/10 4:40:31

Kafka可视化工具实战:生产消费、LAG排查与偏移重置避坑指南

简介&#xff1a;这是一款面向Kafka开发与运维人员的桌面客户端工具&#xff0c;用于连接Kafka集群并完成消息的生产与消费&#xff0c;适合需要快速调试Topic、验证收发链路的初中级开发者。工具支持通过bootstrap、userName、password方式连接&#xff0c;可发送text与json格…

作者头像 李华
网站建设 2026/10/10 4:39:56

千万级数据模糊搜索:MySQL与Elasticsearch组合架构实践

如果你还在用 MySQL 扛搜索需求&#xff0c;我猜你早晚会遇到这么一天&#xff1a;一张千万级的商品表&#xff0c;用户在前端输入两三个字&#xff0c;后端一条LIKE %关键词%打出去&#xff0c;数据库 CPU 瞬间飙高&#xff0c;接口响应卡在两秒开外。我在接手一个内部管理系统…

作者头像 李华
网站建设 2026/10/10 4:39:50

基于Spring Boot的校园二手交易平台设计与实现

校园二手交易平台这个题目&#xff0c;可以说是计算机毕业设计里的“常青树”了。每年都有大量学生会选它&#xff0c;原因很简单&#xff1a;业务场景人人都熟&#xff0c;功能规模适中&#xff0c;既能体现完整的开发流程&#xff0c;又不至于复杂到一个人做不完。市面上相关…

作者头像 李华