文章目录
- 模块介绍
- 主要函数
- 文件和目录操作
- 环境变量操作
- 路径操作
- 系统信息
- 进程管理
- 注意事项
- 总结
模块介绍
os 模块是 Python 标准库的一部分,提供了与操作系统交互的功能,允许我们执行操作系统相关的任务,比如文件操作、进程管理、环境变量操作等。这个模块帮助 Python 程序与操作系统进行低层次的交互,无论是在 Linux、Windows 还是 macOS 系统上,os 模块都能提供统一的接口来进行操作。
主要函数
文件和目录操作
函数 | 描述 |
---|---|
mkdir(path) | 创建一个新目录。如果目录已存在,会抛出 FileExistsError 异常。 |
makedirs(path) | 递归创建目录。如果上级目录不存在,也会一并创建。 |
remove(path) | 删除文件。如果路径指向的是一个目录,则会抛出 IsADirectoryError。 |
rmdir(path) | 删除目录。只会删除空目录,否则会抛出 OSError 异常。 |
removedirs(path) | 递归删除目录,直到找到一个不为空的目录为止。 |
rename(src, dst) | 重命名文件或目录。若目标路径存在同名文件,会抛出 FileExistsError。 |
listdir(path) | 返回指定路径下的文件和目录名的列表。 |
scandir(path) | 返回一个 DirEntry 对象的迭代器,DirEntry 提供了比 listdir 更丰富的文件信息。 |
path.exists(path) | 判断指定路径是否存在,返回布尔值。 |
path.isdir(path) | 判断路径是否是目录,返回布尔值。 |
path.isfile(path) | 判断路径是否是文件,返回布尔值。 |
示例:
import os
# mkdir(path)
# 创建一个新目录。如果目录已存在,会抛出 FileExistsError 异常。
os.mkdir('new_directory') # 创建一个名为 'new_directory' 的目录
# makedirs(path)
# 递归创建目录。如果上级目录不存在,也会一并创建。
os.makedirs('parent_dir/child_dir', exist_ok=True) # 如果 'parent_dir' 不存在,将会一起创建
# remove(path)
# 删除文件。如果路径指向的是一个目录,则会抛出 IsADirectoryError。
os.remove('some_file.txt') # 删除文件 'some_file.txt'
# rmdir(path)
# 删除目录。只会删除空目录,否则会抛出 OSError 异常。
os.rmdir('empty_directory') # 删除空目录 'empty_directory'
# removedirs(path)
# 递归删除目录,直到找到一个不为空的目录为止。
os.removedirs('parent_dir/child_dir') # 删除空目录及其子目录
# rename(src, dst)
# 重命名文件或目录。若目标路径存在同名文件,会抛出 FileExistsError。
os.rename('old_name.txt', 'new_name.txt') # 将 'old_name.txt' 重命名为 'new_name.txt'
# listdir(path)
# 返回指定路径下的文件和目录名的列表。
files = os.listdir('.') # 列出当前目录下的所有文件和文件夹
print(files)
# scandir(path)
# 返回一个 DirEntry 对象的迭代器,DirEntry 提供了比 listdir 更丰富的文件信息。
with os.scandir('.') as it:
for entry in it:
print(entry.name, entry.is_file(), entry.is_dir()) # 打印文件或目录名称,判断其类型
# path.exists(path)
# 判断指定路径是否存在,返回布尔值。
print(os.path.exists('some_path')) # 如果路径存在,返回 True,否则返回 False
# path.isdir(path)
# 判断路径是否是目录,返回布尔值。
print(os.path.isdir('some_directory')) # 如果路径是目录,返回 True,否则返回 False
# path.isfile(path)
# 判断路径是否是文件,返回布尔值。
print(os.path.isfile('some_file.txt')) # 如果路径是文件,返回 True,否则返回 False
- os.mkdir()、os.makedirs()、os.remove()、os.rmdir() 等函数不会自动处理异常,因此如果路径已存在或删除失败,会抛出相应的异常。
- 使用 os.mkdir() 时,如果目录已经存在,将会抛出 FileExistsError。
- 使用 os.rmdir() 删除非空目录时,会抛出 OSError。
- 使用 os.rename() 时,如果目标文件或目录已存在,会抛出 FileExistsError。
环境变量操作
函数 | 描述 |
---|---|
getenv(key, default=None) | 获取环境变量的值。如果指定的环境变量不存在,返回 default。 |
environ | 返回一个表示当前环境变量的字典对象。 |
putenv(key, value) | 设置环境变量,设置后立刻生效,但该值不会出现在 environ 中。 |
unsetenv(key) | 删除环境变量。 |
路径操作
这些函数大多在文件路径操作中非常有用,尤其是在跨平台开发时,自动处理路径分隔符差异可以减少出错的几率。
函数 | 描述 |
---|---|
path.join(path, *paths) | 将一个或多个路径组件拼接成一个路径,确保路径分隔符正确(自动处理不同操作系统的路径分隔符)。 |
path.split(path) | 将路径分割成目录和文件名的二元组 (head, tail)。 |
path.splitext(path) | 分离路径的文件扩展名,返回 (root, ext),ext 包含了文件扩展名,root 为路径本体。 |
path.abspath(path) | 返回路径的绝对路径。如果路径本身是绝对路径,返回它本身;如果是相对路径,则会进行转换。 |
path.normpath(path) | 标准化路径,去除冗余的分隔符、上级目录等。 |
下面是每个 path 模块函数的示例代码,帮助你理解它们如何工作: |
1. path.join(path, *paths)
将多个路径组件拼接成一个路径,并确保路径分隔符正确。
import os
path1 = "/home/user"
path2 = "documents"
path3 = "file.txt"
full_path = os.path.join(path1, path2, path3)
print(full_path) # 输出:/home/user/documents/file.txt
2. path.split(path)
将路径分割为两部分:目录路径和文件名。
import os
path = "/home/user/documents/file.txt"
head, tail = os.path.split(path)
print("目录路径:", head) # 输出:/home/user/documents
print("文件名:", tail) # 输出:file.txt
3. path.splitext(path)
分离路径的文件扩展名。
import os
path = "/home/user/documents/file.txt"
root, ext = os.path.splitext(path)
print("路径本体:", root) # 输出:/home/user/documents/file
print("扩展名:", ext) # 输出:.txt
4. path.abspath(path)
返回路径的绝对路径。如果路径本身是绝对路径,返回它本身;如果是相对路径,则会转换为绝对路径。
import os
path = "documents/file.txt"
absolute_path = os.path.abspath(path)
print(absolute_path) # 输出类似:/home/user/documents/file.txt
5. path.normpath(path)
标准化路径,去除冗余的分隔符、上级目录等。
import os
path = "/home/user//documents/../file.txt"
normalized_path = os.path.normpath(path)
print(normalized_path) # 输出:/home/user/file.txt
系统信息
这些函数可以用来获取操作系统的一些基本信息、进行进程管理和执行系统命令,通常在系统级的脚本编写、调试或监控中非常有用。
函数 | 描述 |
---|---|
name | 返回操作系统的名字:posix(Linux/Unix/macOS)、nt(Windows)、os2、ce、java等。 |
uname() | 返回一个包含操作系统信息的元组(仅限 Unix 系统)。 |
getpid() | 返回当前进程的 ID。 |
getppid() | 返回当前进程的父进程 ID。 |
system(command) | 执行系统的命令,返回命令执行的状态码。 |
1. name
返回当前操作系统的名字,常见的返回值有:
- posix:Linux/Unix/macOS。
- nt:Windows。
- os2、ce、java等。
import os
# 示例
print(os.name) # 输出当前操作系统的名字,例如:posix(Linux/Unix/macOS)或 nt(Windows)
2. uname()
返回一个包含操作系统信息的元组,包含操作系统名称、版本信息、内核名称、机器类型等信息。该函数仅适用于 Unix 系统(如 Linux、macOS)。
import os
# 示例
if os.name == 'posix': # 仅在 Unix 系统中有效
uname_info = os.uname()
print(uname_info)
# 输出类似:
# posix.uname_result(sysname='Linux', nodename='mycomputer', release='5.4.0', version='#45-Ubuntu SMP Fri Jul 17 17:57:37 UTC 2020', machine='x86_64')
3. getpid()
返回当前进程的进程 ID。
import os
# 示例
pid = os.getpid()
print(f"当前进程的 ID: {pid}")
4. getppid()
返回当前进程的父进程 ID。
import os
# 示例
ppid = os.getppid()
print(f"当前进程的父进程 ID: {ppid}")
5. system(command)
执行操作系统的命令,并返回命令执行的状态码。该函数会在一个子进程中执行命令,返回命令的退出状态(通常为 0 表示成功,非 0 表示失败)。
import os
# 示例
status = os.system('echo Hello, World!')
print(f"命令执行状态码: {status}") # 输出:0 表示命令成功执行
# 执行其他系统命令
status = os.system('ls')
print(f"命令执行状态码: {status}")
进程管理
- os.fork() 用于创建子进程(只适用于 Unix 系统)。
- os.exec*() 用于在当前进程中执行新的程序,覆盖当前进程的内容。
- os.spawn*() 用于创建子进程并执行指定的命令,它们在创建进程时更高层次地封装了 fork() 和 exec()。
- os.popen() 用于执行外部命令并返回命令输出的文件对象,可以方便地读取外部程序的结果。
这些操作通常用于需要进程间通信、创建子进程或者执行外部命令的场景。
函数 | 描述 |
---|---|
fork() | 在 Unix 系统中,创建一个子进程。 |
exec*() | 用于在当前进程中执行一个新的程序(覆盖当前进程的内容)。 |
spawn*() | 创建一个子进程并执行指定的命令。 |
popen(command) | 打开一个管道,执行指定的命令并获取输出。 |
以下是与进程创建和管理相关的几个函数的使用示例,适用于 Unix 系统(例如 Linux 和 macOS)。请注意,这些操作系统特定的函数通常无法在 Windows 上使用。 |
1. fork()
os.fork() 在 Unix 系统中创建一个子进程。调用该函数后,父进程会得到子进程的 PID(进程 ID),而子进程会得到 0。通常你可以通过判断返回值来区分父进程和子进程。
import os
# 示例:创建一个子进程
pid = os.fork()
if pid > 0:
# 这是父进程
print(f"这是父进程,子进程的 PID 是 {pid}")
elif pid == 0:
# 这是子进程
print("这是子进程")
else:
print("创建进程失败")
2. exec*()系列
os.exec*() 系列函数用于在当前进程中执行新的程序,替换当前进程的内容。它们不会返回,因为它们会完全替代当前进程的映像。常见的变体有 execv(), execvp() 等。
示例:使用 os.execvp() 来执行一个新的程序:
import os
# 示例:在当前进程中执行一个新的程序(如执行 `ls` 命令)
os.execvp("ls", ["ls", "-l"]) # 将当前进程替换为执行 'ls -l' 的进程
注意:os.exec*() 会使得当前的 Python 进程被新的进程替换,所以代码执行到此时就不会返回。
3. spawn*()系列
os.spawn*() 系列函数用于创建一个子进程并执行指定的命令。这些函数类似于 fork() 和 exec(),但是它们提供了更高层次的接口来管理进程。
示例:使用 os.spawnlp() 创建一个子进程并执行指定的命令。
import os
# 示例:使用 os.spawnlp 执行 `ls -l` 命令
pid = os.spawnlp(os.P_WAIT, "ls", "ls", "-l")
print(f"子进程的 PID 是 {pid}")
- os.P_WAIT 表示父进程会等待子进程执行完毕,os.P_NOWAIT 则表示父进程不会等待子进程结束。
- os.spawnlp() 的第一个参数是一个标志,后面的参数是传递给命令的参数。
4. popen(command)
os.popen(command) 打开一个管道,执行指定的命令并返回一个文件对象,可以通过该文件对象读取命令的输出。适用于需要与外部程序交互并获取输出的场景。
import os
# 示例:通过管道执行 `ls -l` 命令并获取输出
with os.popen("ls -l") as pipe:
output = pipe.read()
print("命令输出:")
print(output)
- os.popen() 执行命令并返回一个文件对象,你可以通过 .read() 方法获取命令输出。
- os.popen() 相当于通过管道(pipe)与子进程交互。
注意事项
- 平台差异:os 模块的一些功能(如 os.fork())是平台特定的,仅在 Unix/Linux 系统中可用,Windows 不支持该功能。因此,在编写跨平台代码时,需要注意这些差异。
- 文件路径格式:虽然 os.path 模块能够处理跨平台的路径问题,但需要小心 Windows 和类 Unix 系统在路径分隔符上的差异(Windows 使用 \,类 Unix 系统使用 /)。os.path.join() 可以有效解决这个问题。
- 权限问题:某些操作,如创建目录、删除文件等,可能会受到操作系统权限的限制,尤其是在 Linux 或 macOS 上,可能需要管理员权限。
总结
os 模块是 Python 中用于与操作系统交互的核心模块之一,提供了文件、目录操作、环境变量管理、路径操作、进程控制等多种功能。掌握 os 模块的使用能帮助开发者高效地与操作系统交互,编写跨平台的 Python 程序。