在日常的 Python 开发中,文件夹操作是一项非常基础且频繁使用的技能。无论是处理数据文件、管理项目结构,还是批量处理文档,都离不开对文件夹的创建、删除、遍历等操作。本文将详细介绍 Python 中操作文件夹的各种方法,从基础的路径处理到高级的批量操作,帮助你轻松掌握这一必备技能。
一、路径处理:OS 模块的核心功能
在进行文件夹操作之前,我们首先需要了解如何处理文件路径。Python 的 os 模块提供了一系列用于处理文件路径的函数,让我们能够轻松应对不同操作系统下的路径格式差异。
1.1 获取当前工作目录
使用os.getcwd()函数可以获取当前 Python 脚本的工作目录,返回一个字符串表示的路径:
import os
current_dir = os.getcwd()
print("当前工作目录:", current_dir)
1.2 切换工作目录
os.chdir(path)函数可以改变当前工作目录到指定的路径。如果路径不存在,会抛出FileNotFoundError异常:
import os
try:
os.chdir("/path/to/new/directory")
print("切换工作目录成功")
except FileNotFoundError:
print("指定的路径不存在")
1.3 路径拼接
不同操作系统使用的路径分隔符不同(Windows 使用反斜杠\,Linux 和 macOS 使用正斜杠/)。为了让代码具有跨平台性,我们应该使用os.path.join()函数来拼接路径:
import os
dir_name = "data"
file_name = "example.txt"
full_path = os.path.join(dir_name, file_name)
print("拼接后的路径:", full_path) # 在Windows上输出"data\example.txt",在Linux/macOS上输出"data/example.txt"
1.4 路径分解
os.path.split()函数可以将一个路径分解为目录和文件名两部分,返回一个元组:
import os
path = "/home/user/documents/report.pdf"
dir_part, file_part = os.path.split(path)
print("目录部分:", dir_part) # 输出"/home/user/documents"
print("文件部分:", file_part) # 输出"report.pdf"
此外,os.path.dirname()和os.path.basename()函数分别用于获取路径中的目录部分和文件名部分:
import os
path = "/home/user/documents/report.pdf"
print("目录部分:", os.path.dirname(path)) # 输出"/home/user/documents"
print("文件部分:", os.path.basename(path)) # 输出"report.pdf"
二、文件夹的创建与删除
掌握了路径处理的基本方法后,我们来学习如何创建和删除文件夹。
2.1 创建单个文件夹
os.mkdir(path)函数用于创建一个新的文件夹。如果文件夹已经存在,会抛出FileExistsError异常:
import os
dir_name = "new_folder"
try:
os.mkdir(dir_name)
print(f"文件夹'{dir_name}'创建成功")
except FileExistsError:
print(f"文件夹'{dir_name}'已经存在")
2.2 创建多级文件夹
如果需要创建多级目录(即父目录可能不存在),可以使用os.makedirs()函数。该函数会递归地创建所有不存在的父目录:
import os
dir_path = "parent_dir/child_dir/grandchild_dir"
try:
os.makedirs(dir_path)
print(f"多级文件夹'{dir_path}'创建成功")
except FileExistsError:
print(f"多级文件夹'{dir_path}'已经存在")
os.makedirs()函数还有一个exist_ok参数,设置为True时,如果文件夹已经存在,不会抛出异常:
import os
dir_path = "parent_dir/child_dir/grandchild_dir"
os.makedirs(dir_path, exist_ok=True) # 如果文件夹已存在,不会报错
2.3 删除单个文件夹
os.rmdir(path)函数用于删除一个空文件夹。如果文件夹不为空或不存在,会抛出相应的异常:
import os
dir_name = "empty_folder"
try:
os.rmdir(dir_name)
print(f"文件夹'{dir_name}'删除成功")
except OSError as e:
print(f"删除文件夹失败:{e}")
2.4 删除非空文件夹
要删除包含文件或子文件夹的非空文件夹,可以使用shutil.rmtree()函数。需要注意的是,这个操作非常危险,删除的文件无法恢复,使用时一定要谨慎:
import shutil
dir_name = "non_empty_folder"
try:
shutil.rmtree(dir_name)
print(f"文件夹'{dir_name}'及其内容删除成功")
except OSError as e:
print(f"删除文件夹失败:{e}")
三、文件夹的遍历与查询
在处理文件时,我们经常需要遍历文件夹中的所有文件和子文件夹,或者查询文件夹的相关信息。
3.1 列出文件夹内容
os.listdir(path)函数返回指定路径下的所有文件和文件夹的名称列表:
import os
dir_path = "."
contents = os.listdir(dir_path)
print(f"{dir_path}下的内容:")
for item in contents:
print(item)
3.2 递归遍历文件夹
os.walk(top)函数可以递归地遍历top目录下的所有文件和子目录,返回一个生成器,每次迭代返回一个元组(dirpath, dirnames, filenames),其中:
- dirpath是当前正在遍历的目录路径
- dirnames是当前目录下的所有子目录名称列表
- filenames是当前目录下的所有文件名称列表
下面是一个使用os.walk()遍历文件夹并打印所有文件路径的例子:
import os
root_dir = "data"
for dirpath, dirnames, filenames in os.walk(root_dir):
print(f"当前目录:{dirpath}")
for filename in filenames:
file_path = os.path.join(dirpath, filename)
print(f"文件:{file_path}")
3.3 判断路径类型
os.path.isdir(path)和os.path.isfile(path)函数分别用于判断指定路径是否为文件夹和文件:
import os
path1 = "documents"
path2 = "image.jpg"
print(f"{path1}是文件夹吗?{os.path.isdir(path1)}")
print(f"{path2}是文件吗?{os.path.isfile(path2)}")
3.4 获取文件信息
os.path.getsize(path)函数可以获取指定文件的大小(以字节为单位),os.path.getmtime(path)函数可以获取文件的最后修改时间(时间戳格式):
import os
import time
file_path = "report.pdf"
if os.path.isfile(file_path):
file_size = os.path.getsize(file_path)
modify_time = os.path.getmtime(file_path)
# 将时间戳转换为可读性更好的格式
modify_time_str = time.ctime(modify_time)
print(f"{file_path}的大小:{file_size}字节")
print(f"{file_path}的最后修改时间:{modify_time_str}")
四、实用案例:批量处理文件夹
掌握了上述基本操作后,我们可以结合这些方法实现一些实用的文件夹批量处理功能。
4.1 批量创建按日期命名的文件夹
下面的代码可以创建一系列按日期命名的文件夹,例如 "2023-10-01"、"2023-10-02" 等:
import os
from datetime import datetime, timedelta
start_date = datetime(2023, 10, 1)
end_date = datetime(2023, 10, 10)
current_date = start_date
while current_date <= end_date:
folder_name = current_date.strftime("%Y-%m-%d")
try:
os.mkdir(folder_name)
print(f"创建文件夹:{folder_name}")
except FileExistsError:
print(f"文件夹{folder_name}已存在,跳过")
current_date += timedelta(days=1)
4.2 按文件类型分类整理文件
这个例子将指定文件夹中的文件按照扩展名进行分类,将不同类型的文件移动到相应的子文件夹中:
import os
import shutil
source_dir = "downloads"
# 定义文件类型与目标文件夹的映射
file_types = {
"txt": "text_files",
"pdf": "pdf_files",
"jpg": "image_files",
"png": "image_files",
"docx": "word_files",
"xlsx": "excel_files"
}
# 遍历源文件夹中的所有文件
for filename in os.listdir(source_dir):
file_path = os.path.join(source_dir, filename)
# 跳过文件夹,只处理文件
if os.path.isfile(file_path):
# 获取文件扩展名(不包含点)
ext = filename.split(".")[-1].lower() if "." in filename else "other"
# 确定目标文件夹
target_folder = file_types.get(ext, "other_files")
target_path = os.path.join(source_dir, target_folder)
# 创建目标文件夹(如果不存在)
os.makedirs(target_path, exist_ok=True)
# 移动文件到目标文件夹
try:
shutil.move(file_path, os.path.join(target_path, filename))
print(f"已将{filename}移动到{target_folder}")
except shutil.Error as e:
print(f"移动{filename}失败:{e}")
4.3 统计文件夹大小
下面的函数可以计算指定文件夹的总大小(包括所有子文件夹和文件):
import os
def get_folder_size(folder_path):
total_size = 0
for dirpath, dirnames, filenames in os.walk(folder_path):
for filename in filenames:
file_path = os.path.join(dirpath, filename)
# 处理可能的符号链接(可选)
if not os.path.islink(file_path):
total_size += os.path.getsize(file_path)
return total_size
folder_path = "documents"
size_bytes = get_folder_size(folder_path)
size_mb = size_bytes / (1024 * 1024) # 转换为MB
print(f"{folder_path}的总大小:{size_bytes}字节(约{size_mb:.2f}MB)")
五、总结与注意事项
本文介绍了 Python 中操作文件夹的常用方法,包括路径处理、文件夹的创建与删除、文件夹的遍历与查询,以及一些实用的批量处理案例。在实际使用中,还需要注意以下几点:
- 跨平台兼容性:尽量使用os.path模块的函数来处理路径,避免直接使用斜杠或反斜杠拼接路径,以保证代码在不同操作系统上都能正常运行。
- 错误处理:文件操作可能会遇到各种异常(如文件不存在、权限不足等),一定要使用try-except语句进行错误处理,使程序更加健壮。
- 操作安全性:删除文件和文件夹的操作非常危险,执行前一定要仔细检查路径是否正确,必要时可以先进行备份。
- 性能考虑:当处理包含大量文件的文件夹时,os.walk()等函数可能会消耗较多资源,需要注意程序的性能。如果只需要处理特定类型的文件,可以在遍历过程中进行过滤,减少不必要的操作。