Python os模块详解
1. 概述
os模块是Python中用于与操作系统进行交互的核心模块,它提供了一系列函数,允许Python程序执行各种操作系统相关的任务,如:
- 文件和目录操作(创建、删除、重命名、遍历等)
- 进程管理(启动新进程、获取进程ID等)
- 环境变量管理
- 路径操作
- 系统信息获取
- 权限管理
os模块是Python标准库的一部分,无需安装即可使用。它提供了跨平台的API,使得相同的代码可以在不同的操作系统(如Windows、Linux、macOS)上运行,同时也允许访问特定于平台的功能。
2. 导入方式
要使用os模块,只需简单地导入即可:
import os
# 或者导入特定的函数
from os import mkdir, rmdir, rename
对于路径操作,通常会同时导入os.path子模块,它提供了专门用于路径处理的函数:
import os
import os.path
# 或者更简洁的方式
from os import path
3. 核心功能分类
3.1 文件和目录操作
3.1.1 文件操作
创建文件
# 创建空文件
def create_empty_file(filename):
open(filename, 'a').close()
create_empty_file("empty.txt")
# 使用os模块创建文件(实际上os模块没有直接创建文件的函数)
# 但可以通过open函数或os.system调用系统命令
os.system("echo '' > newfile.txt") # Windows和Linux都可用
删除文件
# 删除单个文件
os.remove("file.txt")
# 删除多个文件(需要异常处理)
files_to_delete = ["file1.txt", "file2.txt", "file3.txt"]
for file in files_to_delete:
try:
os.remove(file)
print(f"已删除文件: {file}")
except FileNotFoundError:
print(f"文件不存在: {file}")
except PermissionError:
print(f"没有权限删除: {file}")
# 删除只读文件(Windows需要先修改权限)
if os.name == 'nt': # Windows
os.system("attrib -r read-only.txt") # 移除只读属性
os.remove("read-only.txt")
重命名文件
# 重命名文件
os.rename("old_name.txt", "new_name.txt")
# 移动文件(与重命名类似)
os.rename("source/file.txt", "destination/file.txt")
# 使用os.replace(更安全,会覆盖目标文件)
os.replace("old.txt", "new.txt")
复制文件
# os模块本身没有直接复制文件的函数,需要使用shutil模块
import shutil
shutil.copy("source.txt", "destination.txt") # 复制文件内容和权限
shutil.copy2("source.txt", "destination.txt") # 复制文件内容、权限和元数据
文件属性
# 获取文件大小(字节)
size = os.path.getsize("file.txt")
print(f"文件大小: {size} 字节")
# 获取文件创建时间、修改时间、访问时间
import datetime
mtime = os.path.getmtime("file.txt") # 修改时间
time_str = datetime.datetime.fromtimestamp(mtime).strftime("%Y-%m-%d %H:%M:%S")
print(f"文件修改时间: {time_str}")
ctime = os.path.getctime("file.txt") # 创建时间(Windows)或元数据修改时间(Unix)
atime = os.path.getatime("file.txt") # 访问时间
# 检查文件是否存在
if os.path.exists("file.txt"):
print("文件存在")
# 检查是否为文件
if os.path.isfile("file.txt"):
print("这是一个文件")
3.1.2 目录操作
创建目录
# 创建单个目录
os.mkdir("new_dir")
# 创建多级目录
os.makedirs("parent/child/grandchild", exist_ok=True)
# exist_ok=True参数:如果目录已存在,不会抛出异常
删除目录
# 删除空目录
os.rmdir("empty_dir")
# 删除多级目录(需要确保目录为空)
os.removedirs("parent/child/grandchild")
# removedirs会尝试递归删除目录,只有当所有父目录都是空的时才会删除
# 删除非空目录(需要使用shutil模块)
import shutil
shutil.rmtree("non_empty_dir") # 危险操作,谨慎使用
重命名目录
# 重命名目录
os.rename("old_dir", "new_dir")
# 移动目录
os.rename("source/dir", "destination/dir")
目录内容
# 列出目录内容
contents = os.listdir(".")
print("当前目录内容:", contents)
# 列出目录内容(包含详细信息)
for item in contents:
item_path = os.path.join(".", item)
if os.path.isfile(item_path):
print(f"文件: {item} (大小: {os.path.getsize(item_path)} 字节)")
elif os.path.isdir(item_path):
print(f"目录: {item}")
遍历目录
# 递归遍历目录(os.walk)
for root, dirs, files in os.walk("."):
print(f"当前目录: {root}")
print(f"子目录: {dirs}")
print(f"文件: {files}")
print("---")
# 使用os.scandir(更高效)
with os.scandir(".") as entries:
for entry in entries:
if entry.is_file():
print(f"文件: {entry.name}")
elif entry.is_dir():
print(f"目录: {entry.name}")
当前工作目录
# 获取当前工作目录
cwd = os.getcwd()
print(f"当前工作目录: {cwd}")
# 改变当前工作目录
os.chdir("/path/to/new/directory")
print(f"新的工作目录: {os.getcwd()}")
# 切换回原工作目录
os.chdir(cwd)
3.2 路径操作
os模块提供了丰富的路径操作功能,主要通过os.path子模块实现:
路径拼接
# 使用os.path.join拼接路径(推荐,会自动处理路径分隔符)
path1 = os.path.join("parent", "child", "file.txt")
print(path1) # parent/child/file.txt (Linux/macOS) 或 parent\child\file.txt (Windows)
# 直接拼接(不推荐,跨平台问题)
path2 = "parent" + "/" + "child" + "/" + "file.txt" # 在Windows上会有问题
路径拆分
# 拆分路径为目录名和文件名
full_path = "/home/user/documents/file.txt"
dir_name, file_name = os.path.split(full_path)
print(f"目录名: {dir_name}") # /home/user/documents
print(f"文件名: {file_name}") # file.txt
# 拆分路径为驱动器和路径(Windows特有)
if os.name == 'nt':
drive, path = os.path.splitdrive("C:\\Users\\user\\file.txt")
print(f"驱动器: {drive}") # C:
print(f"路径: {path}") # \Users\user\file.txt
# 获取文件扩展名
base_name, extension = os.path.splitext("file.txt")
print(f"基本名称: {base_name}") # file
print(f"扩展名: {extension}") # .txt
路径规范化
# 规范化路径(处理..和.)
path = "/home/user/../documents/./file.txt"
normalized_path = os.path.normpath(path)
print(normalized_path) # /home/documents/file.txt
# 获取绝对路径
relative_path = "../documents/file.txt"
absolute_path = os.path.abspath(relative_path)
print(absolute_path) # /home/documents/file.txt
# 检查路径是否为绝对路径
print(os.path.isabs("/home/user/file.txt")) # True
print(os.path.isabs("../file.txt")) # False
路径检查
# 检查路径是否存在
print(os.path.exists("/home/user/file.txt"))
# 检查是否为文件
print(os.path.isfile("/home/user/file.txt"))
# 检查是否为目录
print(os.path.isdir("/home/user/documents"))
# 检查是否为符号链接
print(os.path.islink("/home/user/link.txt"))
# 检查是否为挂载点
print(os.path.ismount("/")) # Linux/macOS
3.3 进程管理
3.3.1 执行系统命令
# 使用os.system执行系统命令
os.system("dir") # Windows列出目录
os.system("ls -la") # Linux/macOS列出目录
# 执行命令并获取返回值
result = os.system("echo 'Hello World'")
print(f"命令返回值: {result}") # 0表示成功
# 使用os.popen执行命令并获取输出
output = os.popen("whoami").read()
print(f"当前用户: {output.strip()}")
# 更强大的 subprocess 模块(推荐用于复杂命令)
import subprocess
result = subprocess.run(["ls", "-la"], capture_output=True, text=True)
print(result.stdout)
3.3.2 进程信息
# 获取当前进程ID
pid = os.getpid()
print(f"当前进程ID: {pid}")
# 获取父进程ID
ppid = os.getppid()
print(f"父进程ID: {ppid}")
# 终止进程(不推荐,使用subprocess更好)
os.kill(pid, signal.SIGTERM) # 需要导入signal模块
3.3.3 环境变量
# 获取所有环境变量
env_vars = os.environ
print("所有环境变量:", env_vars)
# 获取特定环境变量
path = os.environ.get("PATH")
home = os.environ.get("HOME") # Linux/macOS
user_profile = os.environ.get("USERPROFILE") # Windows
print(f"PATH: {path}")
print(f"HOME: {home}")
print(f"USERPROFILE: {user_profile}")
# 设置环境变量
os.environ["NEW_VAR"] = "new_value"
print(f"NEW_VAR: {os.environ.get('NEW_VAR')}")
# 删除环境变量
del os.environ["NEW_VAR"]
print(f"NEW_VAR是否存在: {'NEW_VAR' in os.environ}")
3.4 系统信息
# 获取操作系统名称
os_name = os.name
print(f"操作系统名称: {os_name}") # 'nt'表示Windows, 'posix'表示Linux/macOS
# 获取详细的系统信息
if os_name == 'nt':
# Windows
print(f"Windows版本: {os.sys.getwindowsversion()}")
else:
# Linux/macOS
print(f"Unix版本: {os.uname()}")
# 获取登录用户
if os_name == 'nt':
print(f"当前用户: {os.getlogin()}")
else:
print(f"当前用户: {os.getlogin()}")
# 获取系统的换行符
print(f"系统换行符: {repr(os.linesep)}")
# 获取路径分隔符
print(f"路径分隔符: {os.sep}")
# 获取环境变量分隔符
print(f"环境变量分隔符: {os.pathsep}")
3.5 权限管理
# 获取文件权限(Linux/macOS)
if os.name != 'nt':
import stat
file_stats = os.stat("file.txt")
permissions = oct(file_stats.st_mode)[-3:]
print(f"文件权限: {permissions}")
# 检查特定权限
is_readable = bool(file_stats.st_mode & stat.S_IRUSR)
is_writable = bool(file_stats.st_mode & stat.S_IWUSR)
is_executable = bool(file_stats.st_mode & stat.S_IXUSR)
print(f"所有者可读: {is_readable}")
print(f"所有者可写: {is_writable}")
print(f"所有者可执行: {is_executable}")
# 修改文件权限(Linux/macOS)
if os.name != 'nt':
os.chmod("file.txt", 0o755) # rwxr-xr-x
print(f"修改后的权限: {oct(os.stat('file.txt').st_mode)[-3:]}")
# 修改文件所有者(需要足够权限)
if os.name != 'nt':
try:
os.chown("file.txt", 1000, 1000) # uid=1000, gid=1000
except PermissionError:
print("没有权限修改所有者")
3.6 其他功能
文件描述符操作
# 打开文件获取文件描述符
fd = os.open("file.txt", os.O_RDONLY)
print(f"文件描述符: {fd}")
# 读取文件内容
content = os.read(fd, 100) # 读取100个字节
print(f"读取的内容: {content.decode('utf-8')}")
# 关闭文件描述符
os.close(fd)
# 复制文件描述符
fd1 = os.open("file.txt", os.O_RDONLY)
fd2 = os.dup(fd1)
print(f"原文件描述符: {fd1}, 复制的文件描述符: {fd2}")
os.close(fd1)
os.close(fd2)
随机数生成
# 获取随机字节串
random_bytes = os.urandom(16) # 生成16个随机字节
print(f"随机字节串: {random_bytes}")
print(f"十六进制表示: {random_bytes.hex()}")
终端大小
# 获取终端大小
try:
rows, columns = os.popen('stty size', 'r').read().split()
print(f"终端大小: {rows}行 x {columns}列")
except:
print("无法获取终端大小")
# 使用os.get_terminal_size(Python 3.3+)
try:
terminal_size = os.get_terminal_size()
print(f"终端大小: {terminal_size.lines}行 x {terminal_size.columns}列")
except OSError:
print("无法获取终端大小")
4. 常用方法总结
4.1 文件和目录操作
| 函数 | 描述 | 示例 |
|---|---|---|
os.remove(path) |
删除文件 | os.remove("file.txt") |
os.rename(src, dst) |
重命名/移动文件或目录 | os.rename("old.txt", "new.txt") |
os.replace(src, dst) |
重命名文件,会覆盖目标文件 | os.replace("old.txt", "new.txt") |
os.mkdir(path) |
创建目录 | os.mkdir("new_dir") |
os.makedirs(path, exist_ok=False) |
递归创建目录 | os.makedirs("a/b/c") |
os.rmdir(path) |
删除空目录 | os.rmdir("empty_dir") |
os.removedirs(path) |
递归删除目录 | os.removedirs("a/b/c") |
os.listdir(path) |
列出目录内容 | os.listdir(".") |
os.scandir(path) |
高效列出目录内容 | with os.scandir(".") as entries: |
os.walk(top) |
递归遍历目录 | for root, dirs, files in os.walk("."): |
os.getcwd() |
获取当前工作目录 | os.getcwd() |
os.chdir(path) |
改变当前工作目录 | os.chdir("/path/to/dir") |
4.2 路径操作(os.path)
| 函数 | 描述 | 示例 |
|---|---|---|
os.path.join(path1, path2, ...) |
拼接路径 | os.path.join("a", "b", "c.txt") |
os.path.split(path) |
拆分路径 | os.path.split("a/b/c.txt") |
os.path.splitext(path) |
拆分扩展名 | os.path.splitext("file.txt") |
os.path.abspath(path) |
获取绝对路径 | os.path.abspath("./file.txt") |
os.path.normpath(path) |
规范化路径 | os.path.normpath("a/../b/c.txt") |
os.path.exists(path) |
检查路径是否存在 | os.path.exists("file.txt") |
os.path.isfile(path) |
检查是否为文件 | os.path.isfile("file.txt") |
os.path.isdir(path) |
检查是否为目录 | os.path.isdir("dir") |
os.path.islink(path) |
检查是否为符号链接 | os.path.islink("link.txt") |
os.path.getsize(path) |
获取文件大小 | os.path.getsize("file.txt") |
os.path.getmtime(path) |
获取修改时间 | os.path.getmtime("file.txt") |
os.path.getctime(path) |
获取创建/元数据修改时间 | os.path.getctime("file.txt") |
4.3 进程和环境
| 函数 | 描述 | 示例 |
|---|---|---|
os.system(command) |
执行系统命令 | os.system("dir") |
os.popen(command) |
执行命令并获取输出 | os.popen("whoami").read() |
os.getpid() |
获取当前进程ID | os.getpid() |
os.getppid() |
获取父进程ID | os.getppid() |
os.environ |
获取环境变量 | os.environ["PATH"] |
os.environ.get(key) |
获取环境变量(安全) | os.environ.get("HOME") |
4.4 系统信息
| 函数 | 描述 | 示例 |
|---|---|---|
os.name |
获取操作系统名称 | os.name |
os.uname() |
获取Unix系统信息 | os.uname() |
os.getlogin() |
获取当前登录用户 | os.getlogin() |
os.sep |
获取路径分隔符 | os.sep |
os.pathsep |
获取环境变量分隔符 | os.pathsep |
os.linesep |
获取系统换行符 | os.linesep |
5. 最佳实践
5.1 跨平台兼容性
# 推荐使用os.path.join而不是直接拼接路径
# 错误示例
path = "a" + "/" + "b" + "/" + "c.txt" # 在Windows上会有问题
# 正确示例
path = os.path.join("a", "b", "c.txt") # 跨平台兼容
# 使用os.sep而不是硬编码路径分隔符
path = os.sep.join(["a", "b", "c.txt"])
# 检查操作系统
if os.name == 'nt': # Windows
# Windows特定代码
pass
else: # Linux/macOS
# Unix特定代码
pass
5.2 异常处理
# 总是处理文件操作可能的异常
def safe_remove(file_path):
try:
os.remove(file_path)
return True
except FileNotFoundError:
print(f"文件不存在: {file_path}")
return False
except PermissionError:
print(f"没有权限删除: {file_path}")
return False
except Exception as e:
print(f"删除文件时出错: {e}")
return False
# 使用os.path.exists检查路径
if os.path.exists(file_path):
# 执行操作
pass
else:
print(f"路径不存在: {file_path}")
5.3 使用上下文管理器
# 使用with语句管理os.scandir
with os.scandir(".") as entries:
for entry in entries:
if entry.is_file():
print(f"文件: {entry.name}")
elif entry.is_dir():
print(f"目录: {entry.name}")
# 自动关闭资源
# 不使用with语句需要手动关闭
entries = os.scandir(".")
try:
for entry in entries:
# 处理条目
pass
finally:
entries.close()
5.4 避免使用os.system
对于复杂的系统命令,推荐使用subprocess模块而不是os.system或os.popen,因为它提供了更强大和安全的功能:
# 错误示例(不安全,易受命令注入攻击)
user_input = "file.txt; rm -rf /" # 恶意输入
os.system(f"cat {user_input}") # 危险!
# 正确示例(安全)
import subprocess
result = subprocess.run(["cat", user_input], capture_output=True, text=True)
print(result.stdout)
5.5 处理大目录
当处理包含大量文件的目录时,使用os.scandir而不是os.listdir,因为它更高效:
# 低效
files = [f for f in os.listdir(".") if os.path.isfile(os.path.join(".", f))]
# 高效
files = [entry.name for entry in os.scandir(".") if entry.is_file()]
6. 常见问题与解决方案
6.1 路径分隔符问题
问题:在不同操作系统上路径分隔符不同(Windows使用\,Linux/macOS使用/)
解决方案:
- 使用
os.path.join拼接路径 - 使用
os.sep获取当前系统的路径分隔符 - 使用
os.path.normpath规范化路径
6.2 文件权限问题
问题:在Linux/macOS上,无法操作某些文件或目录,出现PermissionError
解决方案:
- 检查文件/目录的权限
- 确保程序有足够的权限
- 使用
sudo提升权限(仅Linux/macOS) - 在Windows上,检查文件是否被其他程序占用
6.3 路径不存在问题
问题:尝试操作不存在的文件或目录,出现FileNotFoundError
解决方案:
- 总是使用
os.path.exists检查路径 - 使用异常处理
- 创建路径时使用
os.makedirs(path, exist_ok=True)避免重复创建
6.4 长路径问题
问题:在Windows上,路径过长可能导致FileNotFoundError
解决方案:
- 使用短路径
- 在路径前加上
\\?\前缀(Windows特有)
6.5 符号链接问题
问题:符号链接的处理可能与普通文件/目录不同
解决方案:
- 使用
os.path.islink检查是否为符号链接 - 使用
os.readlink读取符号链接目标 - 使用
os.path.realpath获取符号链接的真实路径
7. 总结
os模块是Python中与操作系统交互的核心模块,提供了丰富的功能,包括:
- 文件和目录操作:创建、删除、重命名、遍历等
- 路径操作:拼接、拆分、规范化、检查等
- 进程管理:执行系统命令、获取进程信息等
- 环境变量:获取、设置、删除环境变量
- 系统信息:获取操作系统名称、版本、用户等
- 权限管理:获取和修改文件权限
使用os模块时,应遵循以下最佳实践:
- 确保跨平台兼容性
- 始终处理异常
- 使用上下文管理器
- 避免使用不安全的
os.system - 高效处理大目录
通过掌握os模块的使用,可以编写更强大、更灵活的Python程序,与操作系统进行深度交互,实现各种复杂的任务。
发布网站:荣殿教程(zhangrongdian.com) 作者:张荣殿 发布日期:2026-01-19