第91集:os模块详解

学习目标

  • 了解os模块的作用和重要性
  • 掌握os模块的文件和目录操作
  • 学会使用os模块管理进程
  • 掌握环境变量的操作
  • 学会获取系统信息
  • 了解路径操作的最佳实践

一、os模块概述

1.1 什么是os模块

os模块是Python标准库中与操作系统交互的核心模块,提供了大量与操作系统相关的功能。它允许Python程序执行各种系统级操作,如文件管理、进程控制、环境变量访问等。

1.2 os模块的主要功能

  • 文件和目录操作
  • 进程管理
  • 环境变量访问
  • 系统信息获取
  • 路径操作
  • 文件权限管理
  • 系统命令执行

1.3 导入os模块

import os

二、文件和目录操作

2.1 获取当前工作目录

import os

# 获取当前工作目录
current_dir = os.getcwd()
print(f"当前工作目录: {current_dir}")

2.2 改变工作目录

import os

# 改变工作目录
os.chdir('/path/to/directory')
print(f"新的工作目录: {os.getcwd()}")

2.3 创建目录

import os

# 创建单个目录
os.mkdir('new_directory')

# 创建多级目录
os.makedirs('parent/child/grandchild', exist_ok=True)

2.4 删除目录

import os

# 删除空目录
os.rmdir('empty_directory')

# 删除目录及其内容
import shutil
shutil.rmtree('directory_with_content')

2.5 列出目录内容

import os

# 列出目录内容
items = os.listdir('.')
print(f"目录内容: {items}")

# 列出所有文件和目录
for item in os.listdir('.'):
    print(item)

2.6 文件和目录重命名

import os

# 重命名文件或目录
os.rename('old_name.txt', 'new_name.txt')

# 移动文件或目录
os.rename('source.txt', 'destination/source.txt')

2.7 删除文件

import os

# 删除文件
os.remove('file.txt')

# 删除多个文件
for file in ['file1.txt', 'file2.txt']:
    if os.path.exists(file):
        os.remove(file)

2.8 文件和目录信息

import os
import time

# 获取文件状态信息
stat_info = os.stat('file.txt')
print(f"文件大小: {stat_info.st_size} 字节")
print(f"最后访问时间: {time.ctime(stat_info.st_atime)}")
print(f"最后修改时间: {time.ctime(stat_info.st_mtime)}")
print(f"创建时间: {time.ctime(stat_info.st_ctime)}")

# 检查文件或目录是否存在
if os.path.exists('file.txt'):
    print("文件存在")

# 检查是否为文件
if os.path.isfile('file.txt'):
    print("这是一个文件")

# 检查是否为目录
if os.path.isdir('directory'):
    print("这是一个目录")

2.9 遍历目录树

import os

# 遍历目录树
for root, dirs, files in os.walk('directory'):
    print(f"当前目录: {root}")
    print(f"子目录: {dirs}")
    print(f"文件: {files}")
    print("-" * 50)

三、路径操作

3.1 路径拼接

import os

# 路径拼接
path = os.path.join('folder', 'subfolder', 'file.txt')
print(f"拼接后的路径: {path}")

3.2 路径分割

import os

# 分割路径
path = '/home/user/documents/file.txt'
dirname, basename = os.path.split(path)
print(f"目录名: {dirname}")
print(f"文件名: {basename}")

# 分割扩展名
filename, ext = os.path.splitext(basename)
print(f"文件名: {filename}")
print(f"扩展名: {ext}")

3.3 路径规范化

import os

# 规范化路径
path = 'folder/../folder/./file.txt'
normalized = os.path.normpath(path)
print(f"规范化后的路径: {normalized}")

# 获取绝对路径
absolute = os.path.abspath('file.txt')
print(f"绝对路径: {absolute}")

3.4 路径信息

import os

# 获取目录名
dirname = os.path.dirname('/path/to/file.txt')
print(f"目录名: {dirname}")

# 获取文件名
basename = os.path.basename('/path/to/file.txt')
print(f"文件名: {basename}")

# 获取扩展名
ext = os.path.splitext('file.txt')[1]
print(f"扩展名: {ext}")

四、环境变量

4.1 获取环境变量

import os

# 获取环境变量
path = os.environ.get('PATH')
print(f"PATH: {path}")

# 获取环境变量(带默认值)
home = os.environ.get('HOME', '/default/home')
print(f"HOME: {home}")

# 获取所有环境变量
for key, value in os.environ.items():
    print(f"{key} = {value}")

4.2 设置环境变量

import os

# 设置环境变量
os.environ['MY_VAR'] = 'my_value'
print(f"MY_VAR: {os.environ.get('MY_VAR')}")

# 修改环境变量
os.environ['PATH'] = '/new/path:' + os.environ.get('PATH', '')

4.3 删除环境变量

import os

# 删除环境变量
if 'MY_VAR' in os.environ:
    del os.environ['MY_VAR']

五、进程管理

5.1 获取进程ID

import os

# 获取当前进程ID
pid = os.getpid()
print(f"当前进程ID: {pid}")

# 获取父进程ID
ppid = os.getppid()
print(f"父进程ID: {ppid}")

5.2 执行系统命令

import os

# 执行系统命令
os.system('ls -l')

# 获取命令输出
output = os.popen('ls -l').read()
print(output)

5.3 创建子进程

import os

# 创建子进程
pid = os.fork()

if pid == 0:
    print("子进程")
else:
    print(f"父进程,子进程ID: {pid}")

六、文件权限

6.1 获取文件权限

import os
import stat

# 获取文件权限
mode = os.stat('file.txt').st_mode
print(f"文件权限: {oct(mode)}")

# 检查文件权限
if os.access('file.txt', os.R_OK):
    print("文件可读")

if os.access('file.txt', os.W_OK):
    print("文件可写")

if os.access('file.txt', os.X_OK):
    print("文件可执行")

6.2 修改文件权限

import os
import stat

# 修改文件权限
os.chmod('file.txt', 0o644)  # rw-r--r--

# 添加执行权限
os.chmod('script.sh', os.stat('script.sh').st_mode | stat.S_IXUSR)

七、系统信息

7.1 操作系统信息

import os
import platform

# 获取操作系统名称
print(f"操作系统: {os.name}")
print(f"系统: {platform.system()}")
print(f"版本: {platform.version()}")
print(f"架构: {platform.machine()}")

# 检查操作系统类型
if os.name == 'nt':
    print("Windows系统")
elif os.name == 'posix':
    print("POSIX系统(Linux/Unix/Mac)")

7.2 用户信息

import os

# 获取用户信息
print(f"当前用户: {os.getlogin()}")
print(f"用户ID: {os.getuid()}")
print(f"组ID: {os.getgid()}")

7.3 系统资源

import os

# 获取系统信息
print(f"CPU核心数: {os.cpu_count()}")

# 获取页面大小
print(f"页面大小: {os.sysconf('SC_PAGE_SIZE')} 字节")

八、文件描述符

8.1 文件描述符操作

import os

# 打开文件
fd = os.open('file.txt', os.O_RDWR | os.O_CREAT)

# 读取文件
data = os.read(fd, 1024)
print(data.decode())

# 写入文件
os.write(fd, b'Hello, World!')

# 关闭文件
os.close(fd)

8.2 文件描述符复制

import os

# 复制文件描述符
fd = os.open('file.txt', os.O_RDONLY)
fd2 = os.dup(fd)

# 关闭原始文件描述符
os.close(fd)

# 使用复制的文件描述符
os.close(fd2)

九、临时文件和目录

9.1 创建临时文件

import os
import tempfile

# 创建临时文件
temp_file = tempfile.NamedTemporaryFile(delete=False)
print(f"临时文件: {temp_file.name}")

# 写入数据
temp_file.write(b'Temporary data')
temp_file.close()

# 删除临时文件
os.unlink(temp_file.name)

9.2 创建临时目录

import os
import tempfile

# 创建临时目录
temp_dir = tempfile.mkdtemp()
print(f"临时目录: {temp_dir}")

# 使用临时目录
temp_file = os.path.join(temp_dir, 'temp.txt')
with open(temp_file, 'w') as f:
    f.write('Temporary data')

# 删除临时目录
import shutil
shutil.rmtree(temp_dir)

十、os模块的实际应用

10.1 文件备份工具

import os
import shutil
from datetime import datetime

def backup_files(source_dir, backup_dir):
    """备份文件"""
    timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
    backup_path = os.path.join(backup_dir, f'backup_{timestamp}')
    
    # 创建备份目录
    os.makedirs(backup_path, exist_ok=True)
    
    # 复制文件
    for item in os.listdir(source_dir):
        src = os.path.join(source_dir, item)
        dst = os.path.join(backup_path, item)
        
        if os.path.isfile(src):
            shutil.copy2(src, dst)
        elif os.path.isdir(src):
            shutil.copytree(src, dst)
    
    print(f"备份完成: {backup_path}")

# 使用
backup_files('source', 'backup')

10.2 文件清理工具

import os
import time

def clean_old_files(directory, days=7):
    """清理旧文件"""
    now = time.time()
    cutoff = now - (days * 86400)
    
    for root, dirs, files in os.walk(directory):
        for file in files:
            file_path = os.path.join(root, file)
            file_mtime = os.path.getmtime(file_path)
            
            if file_mtime < cutoff:
                os.remove(file_path)
                print(f"删除: {file_path}")

# 使用
clean_old_files('temp', days=7)

10.3 目录同步工具

import os
import shutil

def sync_directories(src, dst):
    """同步目录"""
    for item in os.listdir(src):
        src_path = os.path.join(src, item)
        dst_path = os.path.join(dst, item)
        
        if os.path.isfile(src_path):
            if not os.path.exists(dst_path):
                shutil.copy2(src_path, dst_path)
                print(f"复制: {item}")
            elif os.path.getmtime(src_path) > os.path.getmtime(dst_path):
                shutil.copy2(src_path, dst_path)
                print(f"更新: {item}")
        
        elif os.path.isdir(src_path):
            if not os.path.exists(dst_path):
                shutil.copytree(src_path, dst_path)
                print(f"复制目录: {item}")
            else:
                sync_directories(src_path, dst_path)

# 使用
sync_directories('source', 'destination')

10.4 文件查找工具

import os

def find_files(directory, pattern):
    """查找文件"""
    matches = []
    
    for root, dirs, files in os.walk(directory):
        for file in files:
            if pattern in file:
                matches.append(os.path.join(root, file))
    
    return matches

# 使用
files = find_files('.', '.txt')
for file in files:
    print(file)

10.5 磁盘空间检查

import os

def check_disk_space(path):
    """检查磁盘空间"""
    stat = os.statvfs(path)
    
    total = stat.f_blocks * stat.f_frsize
    free = stat.f_bavail * stat.f_frsize
    used = total - free
    
    print(f"总空间: {total / (1024**3):.2f} GB")
    print(f"已使用: {used / (1024**3):.2f} GB")
    print(f"可用空间: {free / (1024**3):.2f} GB")
    print(f"使用率: {(used / total) * 100:.2f}%")

# 使用
check_disk_space('/')

十一、os.path模块

11.1 路径操作

import os.path

# 路径拼接
path = os.path.join('folder', 'file.txt')

# 获取绝对路径
abs_path = os.path.abspath('file.txt')

# 规范化路径
norm_path = os.path.normpath('folder/../folder/./file.txt')

# 获取目录名
dirname = os.path.dirname('/path/to/file.txt')

# 获取文件名
basename = os.path.basename('/path/to/file.txt')

# 分割路径
dirname, basename = os.path.split('/path/to/file.txt')

# 分割扩展名
filename, ext = os.path.splitext('file.txt')

11.2 路径检查

import os.path

# 检查路径是否存在
exists = os.path.exists('/path/to/file')

# 检查是否为文件
is_file = os.path.isfile('/path/to/file')

# 检查是否为目录
is_dir = os.path.isdir('/path/to/dir')

# 检查是否为绝对路径
is_abs = os.path.isabs('/path/to/file')

# 检查路径是否相同
same = os.path.samefile('/path1', '/path2')

11.3 文件信息

import os.path
import time

# 获取文件大小
size = os.path.getsize('file.txt')

# 获取最后访问时间
atime = os.path.getatime('file.txt')
print(f"最后访问时间: {time.ctime(atime)}")

# 获取最后修改时间
mtime = os.path.getmtime('file.txt')
print(f"最后修改时间: {time.ctime(mtime)}")

# 获取创建时间
ctime = os.path.getctime('file.txt')
print(f"创建时间: {time.ctime(ctime)}")

十二、最佳实践

12.1 使用os.path代替字符串操作

# 好的做法
path = os.path.join('folder', 'subfolder', 'file.txt')

# 不好的做法
path = 'folder/subfolder/file.txt'  # 跨平台兼容性差

12.2 检查文件/目录是否存在

# 好的做法
if os.path.exists('file.txt'):
    os.remove('file.txt')

# 不好的做法
os.remove('file.txt')  # 可能抛出异常

12.3 使用上下文管理器

# 好的做法
with open('file.txt', 'r') as f:
    content = f.read()

# 不好的做法
f = open('file.txt', 'r')
content = f.read()
f.close()  # 可能忘记关闭

12.4 处理异常

import os

try:
    os.remove('file.txt')
except FileNotFoundError:
    print("文件不存在")
except PermissionError:
    print("没有权限")

12.5 使用pathlib(Python 3.4+)

from pathlib import Path

# 创建路径
path = Path('folder') / 'subfolder' / 'file.txt'

# 检查是否存在
if path.exists():
    print("路径存在")

# 读取文件
content = path.read_text()

# 写入文件
path.write_text('Hello, World!')

十三、常见问题与解决方案

13.1 跨平台路径问题

问题:路径分隔符在不同操作系统上不同

解决方案

import os

# 使用os.path.join
path = os.path.join('folder', 'file.txt')

13.2 权限问题

问题:没有权限访问文件或目录

解决方案

import os

# 检查权限
if os.access('file.txt', os.R_OK):
    # 读取文件
    with open('file.txt', 'r') as f:
        content = f.read()

13.3 文件名编码问题

问题:文件名包含非ASCII字符

解决方案

import os

# 使用Unicode字符串
filename = '文件.txt'
with open(filename, 'r', encoding='utf-8') as f:
    content = f.read()

13.4 路径长度限制

问题:Windows路径长度限制(260字符)

解决方案

import os

# 使用长路径前缀(Windows)
path = r'\\?\C:\very\long\path\...'

13.5 文件锁定问题

问题:文件被其他进程锁定

解决方案

import os
import time

# 重试机制
max_retries = 3
for i in range(max_retries):
    try:
        with open('file.txt', 'r') as f:
            content = f.read()
        break
    except PermissionError:
        if i < max_retries - 1:
            time.sleep(1)
        else:
            raise

十四、总结

os模块是Python中与操作系统交互的核心模块。本集我们学习了:

  1. 文件和目录操作:创建、删除、重命名、遍历
  2. 路径操作:拼接、分割、规范化
  3. 环境变量:获取、设置、删除
  4. 进程管理:获取进程ID、执行命令
  5. 文件权限:获取、修改权限
  6. 系统信息:操作系统、用户、资源信息
  7. 实际应用:备份、清理、同步、查找工具
  8. 最佳实践:跨平台兼容、异常处理、pathlib

掌握os模块将帮助你更好地与操作系统交互,编写更强大的Python程序。

十五、练习题

  1. 编写一个函数,递归删除目录及其所有内容
  2. 实现一个文件查找工具,支持按名称、大小、时间查找
  3. 编写代码,同步两个目录的内容
  4. 实现一个磁盘空间监控工具
  5. 编写一个文件备份工具,支持增量备份
  6. 实现一个临时文件管理器
  7. 编写代码,获取系统详细信息
  8. 实现一个文件权限管理工具
« 上一篇 配置文件操作 下一篇 » sys模块详解