os操作
文件读写之外,程序还经常需要和操作系统打交道,比如查看当前目录、创建文件夹、获取文件大小、执行系统命令等。Python 内置的 os 模块封装了操作系统提供的接口,可以让我们用统一的代码在不同平台上完成这些操作。
1. os 模块简介
os 模块是 Python 标准库的一部分,使用前需要先导入:
import os它提供的函数与操作系统底层交互,因此某些函数在不同系统上表现不同。可以通过 os.name 快速判断当前操作系统类型:
import os
print(os.name)| 返回值 | 操作系统 |
|---|---|
posix | Linux / Unix / macOS |
nt | Windows |
在类 Unix 系统上,还可以用 os.uname() 获取更详细的系统信息:
import os
print(os.uname())
os.uname()在 Windows 上不可用,调用会抛出AttributeError。
2. 环境变量
操作系统中的环境变量都保存在 os.environ 中,可以像字典一样读取:
import os
# 查看所有环境变量
print(os.environ)获取单个环境变量时,推荐用 get() 方法,并可以指定默认值:
import os
# 获取 PATH
print(os.environ.get('PATH'))
# 获取不存在的变量,返回默认值
print(os.environ.get('NOT_EXIST', 'default'))也可以使用 os.getenv():
import os
print(os.getenv('HOME'))
os.environ.get()与os.getenv()功能基本一致,都支持传入默认值。
3. 路径操作
路径处理函数大多位于 os.path 子模块中。处理路径时应优先使用这些函数,而不是直接拼接字符串,这样可以避免不同操作系统路径分隔符不一致的问题。
3.1 获取绝对路径
import os
print(os.path.abspath('.')) # 当前目录的绝对路径
print(os.path.abspath('test.txt')) # 文件的绝对路径3.2 拼接路径
import os
path = os.path.join('/Users/juzi', 'project', 'test.txt')
print(path)
# Linux / macOS: /Users/juzi/project/test.txt
# Windows: \Users\juzi\project\test.txt3.3 拆分路径
import os
# 拆分为 (目录, 最后一部分)
print(os.path.split('/Users/juzi/project/test.txt'))
# ('/Users/juzi/project', 'test.txt')
# 拆分为 (路径, 扩展名)
print(os.path.splitext('/Users/juzi/project/test.txt'))
# ('/Users/juzi/project/test', '.txt')
# 获取目录名和文件名
print(os.path.dirname('/Users/juzi/project/test.txt'))
# /Users/juzi/project
print(os.path.basename('/Users/juzi/project/test.txt'))
# test.txt
os.path.join()、os.path.split()等函数只处理字符串,不要求路径真实存在。
3.4 规范化路径
import os
# 去除多余的分隔符和 . .. 等
print(os.path.normpath('/Users/./juzi/../project//test.txt'))
# /Users/project/test.txt
# 解析符号链接,返回真实路径
print(os.path.realpath('/path/to/symlink'))4. 目录操作
4.1 获取和切换当前目录
import os
# 获取当前工作目录
print(os.getcwd())
# 切换到指定目录
os.chdir('/Users/juzi/project')
print(os.getcwd())4.2 列出目录内容
import os
# 列出当前目录内容
print(os.listdir())
# 列出指定目录内容
print(os.listdir('/Users/juzi'))4.3 创建目录
import os
# 创建单个目录
os.mkdir('new_folder')
# 递归创建多级目录
os.makedirs('a/b/c', exist_ok=True)
exist_ok=True表示目录已存在时不抛出异常,是makedirs()的常用写法。
4.4 删除目录
import os
# 删除空目录
os.rmdir('new_folder')
# 递归删除空目录
os.removedirs('a/b/c')
os.rmdir()和os.removedirs()只能删除空目录,非空目录会抛出OSError。
5. 文件操作
5.1 重命名和删除
import os
# 重命名文件或目录
os.rename('old.txt', 'new.txt')
# 若目标已存在,replace() 会覆盖,rename() 行为与平台有关
os.replace('old.txt', 'new.txt')
# 删除文件
os.remove('new.txt')
# 等价于
# os.unlink('new.txt')5.2 获取文件信息
import os
# 判断路径是否存在
print(os.path.exists('test.txt'))
# 判断是否为文件或目录
print(os.path.isfile('test.txt'))
print(os.path.isdir('test.txt'))
# 获取文件大小(字节)
print(os.path.getsize('test.txt'))
# 获取详细状态信息
print(os.stat('test.txt'))os.stat() 返回的对象包含文件大小、修改时间、权限等信息,常用属性如下:
| 属性 | 说明 |
|---|---|
st_size | 文件大小(字节) |
st_mtime | 最后修改时间(时间戳) |
st_atime | 最后访问时间(时间戳) |
st_ctime | 创建时间(时间戳,Windows)/ 元数据变更时间(Unix) |
st_mode | 文件类型和权限 |
6. 遍历目录
6.1 os.walk()
os.walk() 可以递归遍历目录树,返回 (dirpath, dirnames, filenames) 三元组:
import os
for dirpath, dirnames, filenames in os.walk('.'):
print(f'目录: {dirpath}')
for filename in filenames:
print(os.path.join(dirpath, filename))6.2 过滤目录和文件
结合列表推导式,可以快速过滤出当前目录下的子目录或特定类型文件:
import os
# 列出当前目录下的所有子目录
print([x for x in os.listdir('.') if os.path.isdir(x)])
# 列出当前目录下的所有 .py 文件
print([x for x in os.listdir('.') if os.path.isfile(x) and os.path.splitext(x)[1] == '.py'])7. 执行系统命令
7.1 os.system()
os.system() 在操作系统的 shell 中执行命令,返回命令的退出状态码:
import os
result = os.system('ls -l')
print(result)返回
0通常表示命令执行成功,非零值表示出错。
7.2 os.popen()
如果需要获取命令的输出,可以使用 os.popen():
import os
with os.popen('ls -l') as f:
print(f.read())更推荐使用
subprocess模块来替代os.system()和os.popen(),功能更强大也更安全。
8. shutil 补充
os 模块没有提供复制文件的函数,因为复制文件不是操作系统直接暴露的系统调用。需要复制文件时,可以使用 shutil 模块:
import shutil
# 复制文件
shutil.copyfile('source.txt', 'dest.txt')
# 复制文件并保留权限
shutil.copy('source.txt', 'dest.txt')
# 复制整个目录树
shutil.copytree('src_dir', 'dst_dir')
shutil可以看作os模块的补充,专门处理文件和目录的高级操作。
9. 常用方法速查
| 方法 | 作用 |
|---|---|
os.name | 当前操作系统类型 |
os.uname() | 获取系统详细信息(Unix 类系统) |
os.environ | 环境变量字典 |
os.getenv(key) | 获取指定环境变量 |
os.getcwd() | 获取当前工作目录 |
os.chdir(path) | 切换当前工作目录 |
os.listdir(path) | 列出目录内容 |
os.mkdir(path) | 创建单个目录 |
os.makedirs(path) | 递归创建目录 |
os.rmdir(path) | 删除空目录 |
os.removedirs(path) | 递归删除空目录 |
os.rename(src, dst) | 重命名文件或目录 |
os.replace(src, dst) | 重命名并覆盖目标 |
os.remove(path) | 删除文件 |
os.unlink(path) | 删除文件(同 remove) |
os.stat(path) | 获取文件状态信息 |
os.system(command) | 执行系统命令 |
os.popen(command) | 执行命令并获取输出 |
os.walk(top) | 递归遍历目录 |
os.path.abspath(path) | 返回绝对路径 |
os.path.join(a, b) | 拼接路径 |
os.path.split(path) | 拆分路径为 (目录, 文件名) |
os.path.splitext(path) | 拆分路径为 (路径, 扩展名) |
os.path.dirname(path) | 获取目录名 |
os.path.basename(path) | 获取文件名 |
os.path.exists(path) | 判断路径是否存在 |
os.path.isfile(path) | 判断是否为文件 |
os.path.isdir(path) | 判断是否为目录 |
os.path.getsize(path) | 获取文件大小 |
os.path.normpath(path) | 规范化路径 |
os.path.realpath(path) | 返回真实路径 |
总结
os 模块是 Python 与操作系统交互的核心工具,重点掌握以下内容:
- 环境变量读取使用
os.environ.get()或os.getenv()。 - 路径操作优先使用
os.path系列函数,不要直接拼接字符串。 - 目录操作注意区分
mkdir/makedirs、rmdir/removedirs,以及空目录限制。 - 文件删除使用
os.remove(),复制文件需要借助shutil.copyfile()。 - 递归遍历目录使用
os.walk(),配合os.path.isfile()等可以快速过滤文件。 - 执行系统命令更推荐使用
subprocess模块,简单场景下也可用os.system()。