Skip to content

Python 操作文件和目录:程序的"文件管理器"

引言:从"手动整理"到"自动管家"

想象你管理一个仓库:

  • 手动整理:自己搬箱子、贴标签、找位置——累,且容易记错;
  • 自动管家(os 模块):告诉管家"把 A 箱子搬到 B 区"、"列出所有红色箱子"——管家自动完成,你只看结果。

Python 的 os 模块就是程序的"文件管家"——创建目录、移动文件、查找筛选,一句话搞定


一、os 模块:操作系统的"遥控器"

1.1 判断操作系统类型

python
import os

print(os.name)   # 'posix' = Linux/Unix/macOS,'nt' = Windows

注意os 模块的某些函数跟操作系统相关——比如 os.uname() 在 Windows 上没有。

1.2 环境变量

python
# 查看所有环境变量
print(os.environ)

# 获取某个环境变量
path = os.environ.get('PATH')
print(path)

# 带默认值
home = os.environ.get('HOME', '/default/home')

生活化理解:环境变量是"仓库的规章制度"——PATH 是"常用工具存放区",HOME 是"管理员办公室"。


二、目录操作:创建、删除、查看

2.1 核心函数

函数作用类比
os.path.abspath('.')当前目录绝对路径你现在站在哪
os.path.join(a, b)拼接路径告诉管家"A区+B货架"
os.mkdir(path)创建目录新建一个货架
os.rmdir(path)删除空目录拆掉空货架

2.2 示例

python
import os

# 查看当前目录
print(os.path.abspath('.'))   # '/Users/michael'

# 拼接路径(自动处理分隔符)
new_dir = os.path.join('/Users/michael', 'testdir')
print(new_dir)   # '/Users/michael/testdir'(Mac)或 'C:\\Users\\michael\\testdir'(Windows)

# 创建目录
os.mkdir(new_dir)

# 删除空目录
os.rmdir(new_dir)

关键路径拼接必须用 os.path.join(),不要手动写 '/''\\'——不同系统分隔符不同。


三、路径拆分:找文件名、找扩展名

3.1 os.path.split():拆目录和文件名

python
os.path.split('/Users/michael/testdir/file.txt')
# ('/Users/michael/testdir', 'file.txt')

生活化理解:像快递单号拆分——"仓库地址 + 包裹编号"。

3.2 os.path.splitext():拆文件名和扩展名

python
os.path.splitext('/path/to/file.txt')
# ('/path/to/file', '.txt')

适用:快速判断文件类型、批量修改扩展名。

注意:这些函数只操作字符串,不要求文件真实存在。


四、文件操作:重命名、删除、复制

4.1 os 模块自带

python
# 重命名
os.rename('test.txt', 'test.py')

# 删除
os.remove('test.py')

4.2 复制文件:shutil 模块

python
import shutil

shutil.copyfile('source.txt', 'dest.txt')

为什么复制不在 os 里? 因为复制不是操作系统的"系统调用",而是"读源文件 + 写目标文件"的组合操作——shutilos 的"补充工具箱"。


五、文件筛选:一行代码找文件

5.1 列出所有目录

python
[x for x in os.listdir('.') if os.path.isdir(x)]
# ['.lein', '.local', '.m2', '.npm', '.ssh', ...]

5.2 列出所有 .py 文件

python
[x for x in os.listdir('.') if os.path.isfile(x) and os.path.splitext(x)[1] == '.py']
# ['apis.py', 'config.py', 'models.py', ...]

核心os.listdir() 列出所有,os.path.isdir() / os.path.isfile() 判断类型,os.path.splitext() 筛扩展名——列表推导式一行搞定


六、知识链条:从"我在哪"到"我要找什么"

当前位置:os.path.abspath('.')

目标路径:os.path.join(当前位置, '子目录')

操作:os.mkdir() / os.rmdir() / os.rename() / os.remove()

筛选:os.listdir() + os.path.isdir()/isfile() + os.path.splitext()

复制:shutil.copyfile()(os 的补充)

七、常见误区与避坑指南

7.1 误区一:路径拼接用字符串相加

python
# ❌ 危险
path = '/Users/michael' + '/' + 'testdir'
path = 'C:\\Users' + '\\' + 'michael'   # Windows 专用

修正os.path.join() 自动适配系统。

7.2 误区二:删除非空目录用 os.rmdir()

python
os.rmdir('/Users/michael/non_empty_dir')   # ❌ OSError: 目录非空

修正:用 shutil.rmtree() 强制删除(谨慎!):

python
import shutil
shutil.rmtree('/Users/michael/non_empty_dir')

7.3 误区三:以为 os.path.exists() 区分文件和目录

python
os.path.exists('/path/to/something')   # 存在就 True,不管是文件还是目录

修正:要区分用 os.path.isfile()os.path.isdir()

7.4 误区四:遍历目录时用相对路径判断

python
for x in os.listdir('subdir'):
    print(os.path.isfile(x))   # ❌ 错!x 是相对当前目录,不是 subdir

修正:用完整路径:

python
for x in os.listdir('subdir'):
    full_path = os.path.join('subdir', x)
    print(os.path.isfile(full_path))

八、实际应用案例

案例 1:项目文件整理器

python
import os
import shutil

def organize_files(target_dir):
    """按扩展名整理目录下的文件到分类文件夹"""
    if not os.path.exists(target_dir):
        print(f'目录不存在: {target_dir}')
        return

    # 定义分类规则
    categories = {
        '图片': ['.jpg', '.jpeg', '.png', '.gif'],
        '文档': ['.txt', '.md', '.doc', '.pdf'],
        '代码': ['.py', '.js', '.html', '.css'],
        '压缩包': ['.zip', '.tar', '.gz']
    }

    for filename in os.listdir(target_dir):
        filepath = os.path.join(target_dir, filename)

        # 跳过目录
        if os.path.isdir(filepath):
            continue

        # 获取扩展名
        _, ext = os.path.splitext(filename)
        ext = ext.lower()

        # 找到分类
        category = '其他'
        for cat, exts in categories.items():
            if ext in exts:
                category = cat
                break

        # 创建分类目录
        cat_dir = os.path.join(target_dir, category)
        if not os.path.exists(cat_dir):
            os.mkdir(cat_dir)

        # 移动文件
        dest = os.path.join(cat_dir, filename)
        shutil.move(filepath, dest)
        print(f'移动: {filename}{category}/')

# 使用
organize_files('/Users/michael/Downloads')

生活化理解:整理器是"仓库分拣机器人"——按包裹类型(扩展名)自动分到不同货架(目录),你只需按按钮。

案例 2:查找大文件

python
import os

def find_large_files(start_dir, size_mb=100):
    """递归查找大于指定大小的文件"""
    size_bytes = size_mb * 1024 * 1024

    for root, dirs, files in os.walk(start_dir):
        for filename in files:
            filepath = os.path.join(root, filename)
            try:
                file_size = os.path.getsize(filepath)
                if file_size > size_bytes:
                    size_mb_actual = file_size / (1024 * 1024)
                    relative_path = os.path.relpath(filepath, start_dir)
                    print(f'{relative_path}: {size_mb_actual:.1f} MB')
            except OSError:
                pass   # 权限不足等错误跳过

# 使用
find_large_files('/Users/michael', size_mb=50)

生活化理解:查找器是"仓库盘点员"——逐个货架检查,发现超重大箱子就记录位置。


九、实战练习

练习 1:实现 dir -l 输出

编写程序,列出当前目录下所有文件和目录的详细信息(名称、大小、类型、修改时间):

python
import os
from datetime import datetime

def list_dir_detail(path='.'):
    # 你的代码
    pass

list_dir_detail()
参考答案
python
import os
from datetime import datetime

def list_dir_detail(path='.'):
    for item in os.listdir(path):
        item_path = os.path.join(path, item)
        stat = os.stat(item_path)

        # 类型
        item_type = '目录' if os.path.isdir(item_path) else '文件'

        # 大小
        size = stat.st_size

        # 修改时间
        mtime = datetime.fromtimestamp(stat.st_mtime).strftime('%Y-%m-%d %H:%M:%S')

        print(f'{item_type:4} {size:>10} bytes  {mtime}  {item}')

list_dir_detail()

练习 2:递归查找文件

在当前目录及所有子目录下,查找文件名包含指定字符串的文件,打印相对路径:

python
import os

def find_files(keyword, start_dir='.'):
    # 你的代码
    pass

find_files('test')
参考答案
python
import os

def find_files(keyword, start_dir='.'):
    for root, dirs, files in os.walk(start_dir):
        for filename in files:
            if keyword in filename:
                full_path = os.path.join(root, filename)
                relative_path = os.path.relpath(full_path, start_dir)
                print(relative_path)

find_files('test')

十、小结

  1. os 模块:操作系统的遥控器,os.name 判断系统类型,os.environ 读环境变量;
  2. 目录操作os.mkdir() 创建、os.rmdir() 删空目录、os.path.abspath() 看当前位置;
  3. 路径处理必须用 os.path.join() 拼接os.path.split() 拆目录/文件名,os.path.splitext() 拆扩展名;
  4. 文件操作os.rename() 重命名、os.remove() 删除、shutil.copyfile() 复制;
  5. 文件筛选os.listdir() + os.path.isdir()/isfile() + 列表推导式,一行搞定;
  6. 递归遍历os.walk() 逐层深入,适合查找、统计、批量处理;
  7. 核心原则路径操作不拼字符串,文件筛选用列表推导,目录遍历用 os.walk()

os 模块是程序的"文件管家"——让代码像资源管理器一样操作文件,但比手动点击快一万倍