os 是 Python 标准库中用于与操作系统交互的模块,可用于管理文件与目录、处理路径、读取环境变量以及获取进程信息。

它为许多常见系统操作提供统一接口,适合批量文件处理、项目目录组织和程序运行环境配置。部分功能具有平台差异,使用时仍需注意操作系统与文件系统的具体行为。

一、导入与常见应用场景

1、导入模块

os 随 Python 提供,无需额外安装。

import os

路径处理功能位于 os.path 中,导入 os 后即可使用。

2、常见应用场景

• 目录管理:获取工作目录、创建目录、列出目录内容。

• 文件操作:重命名文件、删除文件、读取文件状态。

• 路径处理:拼接路径、提取文件名、判断文件类型。

• 目录遍历:递归查找文件,生成文件清单。

• 环境配置:读取与设置环境变量,获取进程标识。

3、与相关模块的分工

• os:侧重操作系统接口、目录操作和运行环境。

• pathlib:以路径对象组织路径处理与常见文件操作。

• shutil:提供文件复制、目录树复制、移动和删除等高级操作。

• subprocess:用于启动外部程序、传递参数和获取执行结果。

这些模块可以配合使用。

读取或写入文件内容时,通常使用内置函数 open() 或 pathlib 的相应方法。

二、核心概念

1、当前工作目录

当前工作目录(Current Working Directory)是程序解析普通相对路径时使用的基准目录。

工作目录由程序的启动方式决定,不一定是脚本文件所在的目录。在终端、编辑器和 Notebook 中运行同一段代码,得到的工作目录可能不同。

2、绝对路径与相对路径

绝对路径(Absolute Path)包含从文件系统根位置定位目标所需的信息;相对路径(Relative Path)则相对于某个基准目录进行定位。

例如:

abspath() 将路径转换为绝对路径,不要求目标已经存在,也不会创建文件。

3、路径与文件系统对象

路径是用于定位文件或目录的表示形式。构造路径、拆分文件名等操作通常只处理路径本身;创建目录、读取状态、删除文件等操作才会访问文件系统。

多数常用 os 文件系统接口既接受路径字符串,也接受 pathlib 的路径对象。

os.makedirs(Path("output"), exist_ok=True)

4、进程与环境变量

进程(Process)是正在运行的程序实例。环境变量(Environment Variable)用于向进程提供配置,例如程序搜索路径、输出目录和运行模式。

os 可以访问当前进程的环境变量,也可以获取当前进程的标识。

三、工作目录与路径处理

1、获取与切换工作目录

    

chdir() 修改当前进程的工作目录,之后使用的相对路径会受到影响。

工作目录由进程内的线程共享。对于需要访问多个目录的程序,通常直接构造目标路径更容易维护,不必频繁切换工作目录。

2、拼接路径

join() 按当前操作系统的路径规则拼接各部分,无需手动添加分隔符。

如果后续部分是绝对路径,前面的路径可能被忽略。因此,不能仅靠拼接来保证目标始终位于指定目录内。

3、提取目录、文件名与扩展名

splitext() 返回去除最后一个扩展名后的部分和扩展名,扩展名包含前导点。

对于 archive.tar.gz,拆分结果是 archive.tar 和 .gz。

4、以脚本所在目录为基准

在普通 Python 脚本中,可以根据 __file__ 构造资源路径:

这样可以减少启动位置变化对路径的影响。交互式解释器和 Notebook 通常没有 __file__,应显式指定基准目录。

5、展开用户主目录

普通文件操作不会自动将路径中的 ~ 展开为用户主目录,需要先调用 expanduser()。

同样,含环境变量的路径可用 expandvars() 展开,但变量展开不会验证目标是否存在。

四、目录创建、列举与遍历

1、创建目录

创建单层目录:

父目录必须存在,且目标目录不能已经存在。

创建多层目录:

makedirs() 会创建缺失的中间目录。exist_ok=True 允许目标目录已经存在;如果目标位置是普通文件,仍会报错。

2、列出目录内容

    

listdir() 返回指定目录中各条目的名称列表,包含文件与子目录,不会递归进入子目录。

返回顺序没有保证;需要稳定顺序时,可使用 sorted()。

3、读取目录条目信息

需要同时判断条目类型或获取状态时,可以使用 scandir():

            

每个条目是一个目录条目对象(DirEntry),可通过 name、path、is_file()、is_dir() 和 stat() 获取信息。

follow_symlinks=False 表示判断时不跟随符号链接。使用 with 可确保迭代结束或发生异常时关闭相关资源。

4、递归遍历目录

            

每次迭代返回三个值:

• root:当前正在遍历的目录路径。

• dirs:当前目录中的子目录名称列表。

• files:当前目录中的非目录条目名称列表。

这些名称不包含当前目录路径,使用时通常需要与 root 拼接。

5、排除目录与处理遍历错误

默认自顶向下遍历时,可以原地修改 dirs,排除不需要进入的目录:

        

这里需要使用 dirs[:] 原地修改列表;仅将 dirs 重新赋值为另一个列表,不能控制后续遍历。

walk() 默认忽略目录扫描过程中产生的错误。需要报告错误时,可设置 onerror;需要停止遍历时,可在回调函数中重新抛出异常。

默认不递归进入指向目录的符号链接。启用 followlinks=True 后应注意循环链接可能导致无限递归。

五、文件判断、状态与修改

1、判断路径类型

• exists():判断路径是否存在。

• isfile():判断是否为现有普通文件。

• isdir():判断是否为现有目录。

上述判断通常会跟随符号链接。exists() 对失效的符号链接返回 False;需要判断链接条目本身是否存在时,可使用 lexists()。

路径判断与后续操作之间,文件状态仍可能变化,因此判断结果不能代替异常处理。

2、读取文件大小与修改时间

以下示例假定 data/students.xlsx 已存在。

stat() 返回文件状态对象(stat_result)。其中,普通文件的 st_size 表示文件大小,st_mtime 表示内容最后修改时间。

也可以分别使用:

modified_time = os.path.getmtime(path)

不宜将 st_ctime 或 getctime() 统一解释为跨平台的“创建时间”,其含义存在平台差异。

3、重命名文件或目录

示例要求源文件存在,目标名称尚未使用。

当目标已经存在时,行为具有平台差异:Windows 通常抛出 FileExistsError;Unix 系统在满足条件时可能直接替换目标文件。

如果明确需要替换已有文件,可使用:

os.replace("new_report.txt", "report.txt")

replace() 在权限允许时替换目标文件。它不是文件复制操作;源路径与目标路径位于不同文件系统时可能失败。需要跨文件系统移动时,可使用 shutil.move()。

4、删除文件与空目录

删除文件:

os.unlink() 与 os.remove() 功能相同。若路径指向符号链接,删除的是链接本身。

删除空目录:

os.rmdir("empty_folder")

rmdir() 不能删除非空目录。需要删除整个目录树时,可使用 shutil.rmtree()。

这些删除操作通常不会将对象移入回收站,应先确认目标路径。

5、处理文件操作异常

    

常见异常还包括 FileExistsError、NotADirectoryError 和 IsADirectoryError。应根据任务处理具体错误,避免直接忽略所有异常。

六、环境变量与进程信息

1、读取环境变量

getenv() 返回环境变量的字符串值;变量不存在时返回指定默认值,未指定默认值时返回 None。

也可以使用:

output_dir = os.environ.get("APP_OUTPUT_DIR", "output")

若使用 os.environ["APP_OUTPUT_DIR"],变量不存在时会抛出 KeyError。

2、设置与删除环境变量

os.environ 的键和值必须是字符串。

这些修改作用于当前进程,并通常由随后启动的子进程继承;不会反向修改启动 Python 的父进程,也不会永久修改系统环境变量。

3、读取系统类型与进程标识

常见的 os.name 值包括:

• "nt":Windows。

• "posix":Linux、macOS 等采用 POSIX 接口的系统。

因此,不能只用 os.name == "posix" 区分 Linux 和 macOS。需要更详细的系统信息时,可使用 sys.platform 或 platform 模块。

4、启动外部程序

os 提供 system() 等接口,但执行外部程序、传递参数和检查结果时,通常使用 subprocess:

这里使用当前 Python 解释器执行命令,并通过参数列表传递参数。

不要把未经处理的外部输入直接拼接到 os.system() 的命令字符串中,以免被命令解释器当作额外指令执行。

七、应用举例:生成文件清单

以下示例递归扫描 data 目录,将普通文件的相对路径、大小和修改时间写入 CSV 文件。

示例不进入符号链接目录,并跳过文件符号链接。请先准备 data 目录及其中的文件。

结果保存在 output/file_list.csv 中。程序按名称排序,便于查看,并对捕获到的访问错误显示提示。无法访问或不符合筛选条件的条目可能不会出现在清单中。

该清单记录扫描时获取的信息,不会自动随文件变化而更新。

八、常用函数与属性速览

以下列出常用调用形式,省略部分可选参数。

• os.getcwd():返回当前工作目录的字符串。

• os.chdir(path):切换当前进程的工作目录。

• os.mkdir(path):创建单层目录。

• os.makedirs(name, exist_ok=False):递归创建目录。

• os.listdir(path="."):返回目录条目名称列表。

• os.scandir(path="."):返回目录条目迭代器。

• os.walk(top, topdown=True, onerror=None, followlinks=False):生成目录树中的路径、子目录名称列表和文件名称列表。

• os.stat(path):返回文件或目录的状态信息。

• os.rename(src, dst):重命名文件或目录。

• os.replace(src, dst):重命名,并在条件允许时替换目标。

• os.remove(path):删除文件或符号链接。

• os.rmdir(path):删除空目录。

• os.getenv(key, default=None):读取环境变量。

• os.environ:访问或修改当前进程的环境变量映射。

• os.path.join(path, *paths):拼接路径。

• os.path.abspath(path):返回绝对路径。

• os.path.relpath(path, start="."):计算相对于起始目录的路径。

• os.path.splitext(path):拆分最后一个扩展名。

上述创建、切换、重命名和删除函数成功时通常返回 None,失败时抛出异常。

九、补充说明

1、平台差异

os 提供统一接口,但不保证所有功能在所有平台上都可用,也不保证权限、文件占用和重命名规则完全一致。

涉及权限设置、进程控制和符号链接时,应确认目标平台的支持情况。

2、Windows 路径书写

在 Python 字符串中直接书写 Windows 路径时,可使用原始字符串:

path = r"C:\Users\Public\Documents"

这样可避免反斜杠被解释为转义序列。原始字符串不能以奇数个反斜杠结束;组合多段路径时,通常使用 os.path.join()。

3、符号链接与文件状态

os.stat() 默认跟随符号链接,返回目标对象的状态。需要读取链接本身的状态时,可使用 os.lstat()。

符号链接(Symbolic Link)可以指向其他文件或目录,也可能因目标被移动或删除而失效。

4、路径规范化的边界

normpath() 用于整理路径中的冗余分隔符、. 和 ..,不验证目标是否存在,也不等同于解析符号链接。

处理外部提供的路径时,还需根据任务验证允许访问的范围;不能将路径拼接或规范化直接视为访问权限检查。

小结

os 提供文件目录管理、路径处理、环境变量和进程信息等操作系统接口。理解工作目录、平台差异与符号链接行为,并结合异常处理,可以更可靠地组织自动化任务;复杂文件操作可配合 pathlib、shutil 和 subprocess 完成。

打开网易新闻 查看精彩图片

“点赞有美意,赞赏是鼓励”