Skip to content

03 os模块

你的代码跑在操作系统上,读写文件、创建目录、获取环境变量、执行系统命令——这些都是操作系统层面的操作。os模块就是Python提供的一套"操作系统接口",让你用Python代码来做这些事情。

os模块最大的价值是跨平台。Windows用反斜杠\,Linux/macOS用正斜杠/;Windows用nt,Linux用posix——os模块帮你抹平这些差异,一套代码到处跑。

一、环境变量

1.1 os.environ

环境变量是操作系统级别的配置,比如PATHHOMEAPI_KEY等。

python
import os

# 获取所有环境变量
os.environ
# environ({'PATH': '/usr/bin', 'HOME': '/Users/apple', ...})

# 获取单个环境变量(返回字符串)
os.environ.get("HOME")        # '/Users/apple'
os.environ.get("API_KEY")     # None(不存在时返回None)
os.environ.get("API_KEY", "") # ''(设置默认值)

# 不存在时会抛KeyError
os.environ["NOT_EXIST"]  # KeyError: 'NOT_EXIST'

# 设置环境变量(仅当前进程有效)
os.environ["API_KEY"] = "sk-xxx"

# 删除环境变量
del os.environ["API_KEY"]

# 或者用pop
os.environ.pop("API_KEY", None)

1.2 os.getenv()

更简洁的获取环境变量方式。

python
import os

# 等价于os.environ.get()
api_key = os.getenv("API_KEY")
db_host = os.getenv("DB_HOST", "localhost")  # 带默认值

读取.env文件时,通常配合python-dotenv

python
from dotenv import load_dotenv
import os

load_dotenv()  # 加载.env文件
api_key = os.getenv("OPENAI_API_KEY")

二、当前工作目录

2.1 os.getcwd()

获取当前工作目录(脚本运行时所在的目录)。

python
import os

cwd = os.getcwd()
print(f"当前目录: {cwd}")
# 当前目录: /Users/apple/project

2.2 os.chdir()

切换工作目录。

python
import os

# 切换到指定目录
os.chdir("/tmp")
print(os.getcwd())  # /tmp

# 切换回上一级
os.chdir("..")

注意os.chdir()会影响整个进程,在多线程环境下要小心使用。

三、目录操作

3.1 创建目录

python
import os

# 创建单级目录
os.mkdir("logs")  # 如果logs已存在,会报FileExistsError

# 创建多级目录(递归创建)
os.makedirs("data/2026/06", exist_ok=True)
# exist_ok=True:目录已存在时不报错

3.2 删除目录

python
import os

# 删除空目录
os.rmdir("logs")  # 目录不为空会报OSError

# 递归删除空目录
os.removedirs("data/2026/06")
# 会依次删除06、2026、data(必须都是空目录)

3.3 列出目录内容

python
import os

# 列出目录下的文件和子目录
files = os.listdir(".")  # 当前目录
files = os.listdir("/Users/apple")  # 指定目录

# 返回的是文件名列表,不含路径
for filename in os.listdir("."):
    print(filename)

3.4 遍历目录树

python
import os

# os.walk()递归遍历目录
for root, dirs, files in os.walk("data"):
    print(f"目录: {root}")
    print(f"  子目录: {dirs}")
    print(f"  文件: {files}")
    print()

os.walk()返回一个生成器,每个元素是(dirpath, dirnames, filenames)

  • dirpath:当前目录路径
  • dirnames:子目录列表
  • filenames:文件列表

3.5 高效目录扫描

python
import os

# os.scandir()比listdir()更高效(3.5+)
with os.scandir(".") as entries:
    for entry in entries:
        if entry.is_file():
            print(f"文件: {entry.name}, 大小: {entry.stat().st_size}")
        elif entry.is_dir():
            print(f"目录: {entry.name}")

os.scandir()返回DirEntry对象,可以直接获取文件类型和状态信息,不需要额外的系统调用。

四、文件操作

4.1 删除文件

python
import os

# 删除文件
os.remove("data.txt")  # 文件不存在会报FileNotFoundError

# os.unlink()是os.remove()的别名
os.unlink("data.txt")

# 安全删除(先检查)
if os.path.exists("data.txt"):
    os.remove("data.txt")

4.2 重命名

python
import os

# 重命名文件或目录
os.rename("old.txt", "new.txt")

# 跨目录移动(也是rename)
os.rename("data.txt", "archive/data.txt")

# 目标已存在时会报错,用os.replace()可以强制覆盖
os.replace("new.txt", "old.txt")

4.3 文件状态

python
import os

# 获取文件状态
stat = os.stat("data.txt")

stat.st_size     # 文件大小(字节)
stat.st_mtime    # 最后修改时间(时间戳)
stat.st_atime    # 最后访问时间
stat.st_ctime    # 创建时间(Unix)/ 元数据修改时间(Windows)
stat.st_mode     # 文件模式(权限等)

# 检查文件访问权限
os.access("data.txt", os.R_OK)  # 可读?
os.access("data.txt", os.W_OK)  # 可写?
os.access("data.txt", os.X_OK)  # 可执行?

# 修改文件权限
os.chmod("script.sh", 0o755)  # 设置为可执行

4.4 创建链接

python
import os

# 创建硬链接
os.link("original.txt", "hardlink.txt")

# 创建符号链接(软链接)
os.symlink("original.txt", "symlink.txt")

# 读取符号链接指向的目标
target = os.readlink("symlink.txt")

五、执行系统命令

5.1 os.system()

执行系统命令,返回退出状态码。

python
import os

# 执行命令
status = os.system("ls -la")
# 0: 成功, 非0: 失败

# 注意:命令输出直接打印到终端,无法捕获

5.2 os.popen()

执行命令并获取输出。

python
import os

# 获取命令输出
with os.popen("ls -la") as f:
    output = f.read()
    print(output)

实际项目中,建议用subprocess模块,它更强大也更安全:

python
import subprocess

result = subprocess.run(["ls", "-la"], capture_output=True, text=True)
print(result.stdout)
print(result.returncode)

六、路径分隔符与常量

6.1 系统常量

python
import os

# 路径分隔符
os.sep      # '/' (Linux/macOS) 或 '\' (Windows)

# 行分隔符
os.linesep  # '\n' (Linux/macOS) 或 '\r\n' (Windows)

# 空设备路径
os.devnull  # '/dev/null' (Linux/macOS) 或 'NUL' (Windows)

# 操作系统名
os.name     # 'posix' (Linux/macOS) 或 'nt' (Windows)

6.2 跨平台路径拼接

python
import os

# 不要手动拼接路径(不跨平台)
path = "data" + "/" + "file.txt"  # 不推荐

# 用os.path.join()(跨平台)
path = os.path.join("data", "file.txt")  # 推荐

七、进程信息

python
import os

# 当前进程ID
os.getpid()    # 12345

# 父进程ID
os.getppid()   # 12340

# 获取登录用户名
os.getlogin()  # 'apple'

# 获取用户ID(Unix)
os.getuid()    # 501

# 获取组ID(Unix)
os.getgid()    # 20

八、随机数

python
import os

# 生成密码学安全的随机字节
random_bytes = os.urandom(16)
print(random_bytes)  # b'\xf3\xa1\x9c...'

# 用于生成随机整数
import struct
random_int = struct.unpack('I', os.urandom(4))[0]

九、实用技巧

9.1 创建临时目录

python
import os
import tempfile

# 创建临时目录
with tempfile.TemporaryDirectory() as tmpdir:
    print(f"临时目录: {tmpdir}")
    # 在这里使用临时目录
    filepath = os.path.join(tmpdir, "data.txt")
    with open(filepath, "w") as f:
        f.write("临时数据")
# 退出with块后,临时目录自动删除

9.2 递归删除目录

python
import os
import shutil

# 删除整个目录(包括非空目录)
shutil.rmtree("data")
# os模块没有直接提供这个功能,需要用shutil

9.3 获取文件大小

python
import os

def get_size(path):
    """获取文件或目录的大小"""
    if os.path.isfile(path):
        return os.path.getsize(path)
    elif os.path.isdir(path):
        total = 0
        for root, dirs, files in os.walk(path):
            for f in files:
                filepath = os.path.join(root, f)
                total += os.path.getsize(filepath)
        return total
    return 0

十、总结

os模块是Python和操作系统之间的桥梁:

分类常用函数/属性
环境变量environ, getenv()
工作目录getcwd(), chdir()
目录操作mkdir(), makedirs(), listdir(), walk(), scandir()
文件操作remove(), rename(), stat(), chmod(), link(), symlink()
系统命令system(), popen()
系统常量sep, linesep, name, devnull
进程信息getpid(), getppid(), getlogin()

os模块的函数很多,不用全记住。最常用的就是os.path(下一章单独讲)、os.environos.listdir()os.makedirs()这几个。遇到具体需求时查文档就行。