文章目录
- [1. 文件路径的操作](#1. 文件路径的操作)
- [2. 复制](#2. 复制)
-
- [2.1 文件的复制](#2.1 文件的复制)
- [2.2 文件夹的复制](#2.2 文件夹的复制)
- [3. 移动(剪切)](#3. 移动(剪切))
- [4. 删除](#4. 删除)
- [5. 新建](#5. 新建)
- [6. 关于隐藏文件的处理方式](#6. 关于隐藏文件的处理方式)
- [7. 三个小案例](#7. 三个小案例)
-
- [7.1 文件分类](#7.1 文件分类)
- [7.2 清理空文件夹](#7.2 清理空文件夹)
- [7.3 文件备份](#7.3 文件备份)
以下是一些os库和shutil库中常用的命令,可以实现各种便捷的文件操作,我们可以通过以下命令进行模块的导入:
python
import os
import shutil
import stat # 当然有的时候我们会想过滤掉隐藏文件,就可以调用这个包
1. 文件路径的操作
在进行文件操作之前,我们首先需要知道文件路径如何给,一般我们通过 r 标识符来告诉程序这个是一个文件路径,例如:
python
folder_path = r"C:\Users\22330\Desktop\进行中"
那么接下来我们就可以在这个文件夹中进行操作了,如果我们需要组合多个路径,就可以使用 os 模块 path 下的 join 功能了,这个的具体作用其实就是加一个 斜杠\ 再连接路径,这样你就可以一直往子文件夹进了:
python
folder_path = r"C:\Users\22330\Desktop\进行中"
file_to_copy = os.path.join(folder_path, "testCopy")
print(file_to_copy) # C:\Users\22330\Desktop\进行中\testCopy
那如果我们想要回到上一层文件夹,应该如何做呢?使用 dirname 即可:
python
folder_path = r"C:\Users\22330\Desktop\进行中"
parent_path = os.path.dirname(folder_path)
print(parent_path) # C:\Users\22330\Desktop
2. 复制
2.1 文件的复制
好,那么我们现在已经知道如何操作路径了,接下来我们看复制 ,需要注意的是,os 模块本身确实没有直接提供文件复制的功能,它只是有文件操作的基础,因此要实现文件的复制,我们可以使用shutil模块,这个会更加方便:
1、这里分两种情况,一种是你复制的时候不保留元信息 ,比如文件创建时间这些,那么就可以用copy方法:
python
folder_path = r"C:\Users\22330\Desktop\进行中\testCopy"
shutil.copy(os.path.join(folder_path, "1.jpg"), os.path.join(folder_path, "1_copy.jpg"))

注意,我是粘贴到了同一个文件夹,这个时候时间是变化了的,代表并没有保留初始的创建日期。
2、第二种就是你需要保留文件的元信息 ,我们就可以使用copy2方法:
python
folder_path = r"C:\Users\22330\Desktop\进行中\testCopy"
shutil.copy2(os.path.join(folder_path, "1.jpg"), os.path.join(folder_path, "1_copy2.jpg"))

这个时候你可以观察到,copy2 保留了原始的元信息。
2.2 文件夹的复制
在程序中,是会非常清楚区分文件夹和文件的,可以通过 os.path.isdir 或者 os.path.isfile 进行区分:
比如 folder_path 下有一个命名为 1 的文件夹,和一个 1.jpg 的图片文件,就可以通过isdir 和 isfile 做区分
python
folder_path = r"C:\Users\22330\Desktop\进行中\testCopy"
print(os.path.isdir(os.path.join(folder_path, "1.jpg"))) # False
print(os.path.isfile(os.path.join(folder_path, "1.jpg"))) # True
print(os.path.isfile(os.path.join(folder_path, "1"))) # False
print(os.path.isdir(os.path.join(folder_path, "1"))) # True
在python中,如果需要复制某个文件夹,只需要使用 shutil 模块下的 copytree 方法,如下:
python
folder_path = r"C:\Users\22330\Desktop\进行中\testCopy"
# 两个参数,第一个是要复制的路径,第二个是存放的路径,同时可以进行文件夹名字的修改
shutil.copytree(os.path.join(folder_path,"1"), os.path.join(folder_path, "1_copy"))

3. 移动(剪切)
如果想要移动某个文件,那么我们完全可以通过 os 模块下的rename方法实现,下面是将1.jpg这张图片移动到上一级目录中
python
folder_path = r"C:\Users\22330\Desktop\进行中\testCopy"
os.rename(os.path.join(folder_path,"1.jpg"), os.path.join(os.path.dirname(folder_path), "1.jpg"))
那如果是想要移动文件夹呢? 我们可以使用shutil.move 方法
python
sourse_folder = r"C:\Users\22330\Desktop\进行中\testCopy\1"
destination_folder = r"C:\Users\22330\Desktop\进行中\new_location"
# 注意这种写法只是将 1 文件夹下所有文件移动到 new_location 下,并不会再在 new_location 下新建一个文件夹为 1
# 如果要保留1文件夹本身,那么就是写作 destination_folder = r"C:\Users\22330\Desktop\进行中\new_location\1"
shutil.move(sourse_folder, destination_folder) # destination_folder如果不存在,会自动新建
或者同样地,我们也可以使用os.rename 方法
python
os.rename(sourse_folder, destination_folder) # destination_folder如果不存在,会自动新建
4. 删除
在python中,如果需要删除文件夹 ,我们可以用os 模块下的rmdir方法:
python
del_folder = r"C:\Users\22330\Desktop\进行中\testCopy\1_copy"
os.rmdir(del_folder)
但是这个方法有一个限制,就是要删除的文件夹一定要是空文件夹,如果是非空文件夹,就会报错:

所以我们有一个更加彻底的方式,就是使用shutil的rmtree方法:
python
del_folder = r"C:\Users\22330\Desktop\进行中\testCopy\1_copy"
shutil.rmtree(del_folder)
那如果我们需要删除的是文件,就可以使用os 的 remove 方法或者unlink方法:
bash
del_file = r"C:\Users\22330\Desktop\进行中\testCopy\1_copy.jpg"
os.remove(del_file)
os.unlink(del_file) # unlink和remove 的功能一样
5. 新建
如果是想要新建一个文件夹,那可以采用os 模块下的mkdir或者makedirs方法,只不过后者多了一个exist_ok的参数,用来指定如果文件夹已经存在,是否会报错,比如我们文件夹已存在的时候,如果使用mkdir:
python
mk_folder = r"C:\Users\22330\Desktop\进行中\testCopy\testFolder"
os.mkdir(mk_folder)
就会报这样的错误:"[WinError 183] 当文件已存在时,无法创建该文件"

但是如果我们使用 makedirs,并给上 exist_ok = True,这个问题就成功解决了:
python
mk_folder = r"C:\Users\22330\Desktop\进行中\testCopy\testFolder"
os.makedirs(mk_folder, exist_ok=True) # 不删除文件夹中原有的文件,且不报错
新建文件的话,就有很多不同的情况了,例如txt,xlsx,jpg,pptx等,这里我们以创建一个最简单的txt文档为例:
python
mk_folder = r"C:\Users\22330\Desktop\进行中\testCopy\testFolder"
txt_to_make = os.path.join(mk_folder, "test.txt")
with open(txt_to_make, "w") as f: # w 代表的是写入状态
f.write("这是一个测试文件")
f.close() # 关闭文件

6. 关于隐藏文件的处理方式
这里就涉及我们上面提到的一个非常重要的包,叫做stat,我们先看一下目录下的隐藏文件:
如果我们文件系统中没有显示隐藏文件,默认是看不见的,但是程序能够找出来
于是我们通过下面的程序打印出所有的文件,listdir 在这里是罗列所有的文件,返回一个列表,我们遍历即可:
python
folder_dir = r"C:\Users\22330\Desktop\进行中"
for item in os.listdir(folder_dir):
print(item)

可以发现,隐藏文件都以~开头,其实有的时候也以 . 开头,如果我们简单写作下面的程序:
python
folder_dir = r"C:\Users\22330\Desktop\进行中"
for file in os.listdir(folder_dir):
# 如果是隐藏文件,不显示
if not file.startswith(".") and not file.startswith("~"):
print(file)
看上去确实没问题,但是容易误伤友军,比如有的文件就是以~开头的:

所以仅仅通过开始字符做判断,是不合理的,因此就引入了我们的stat:
python
folder_dir = r"C:\Users\22330\Desktop\进行中"
for file in os.listdir(folder_dir):
file_name = os.path.join(folder_dir,file)
file_stat = os.stat(file_name) # 获取文件属性
is_hidden = file_stat.st_file_attributes & stat.FILE_ATTRIBUTE_HIDDEN # 按位与 获取隐藏状态
print(is_hidden) # 测试用,为2代表是隐藏文件,为0代表不是隐藏文件
if not is_hidden:
print(file)

7. 三个小案例
7.1 文件分类
你有一个文件夹 data(可以自己新建一个做测试),里面乱七八糟地放着 .txt 文本文件和 .xlsx 文件,需要将文件分类
python
import os
import shutil
folder_dir = r"C:\Users\22330\Desktop\进行中\data" # 文件夹路径
file_type = []
# 统计文件类型
for item in os.listdir(folder_dir):
# 通过splitext获取文件扩展名,并去掉点号
file_type.append(os.path.splitext(item)[1].replace(".",""))
# 为不同文件类型创建文件夹
for tp in list(set(file_type)): # 通过set去重
os.makedirs(os.path.join(folder_dir, tp), exist_ok=True)
# 移动文件到对应的文件夹
for item in os.listdir(folder_dir):
if os.path.isfile(os.path.join(folder_dir, item)): # 如果是文件类型才进行移动
tp = os.path.splitext(item)[1].replace(".","") # 获取文件类型
shutil.move(os.path.join(folder_dir, item), os.path.join(folder_dir, tp, item))
print(f"已移动: {item}")
7.2 清理空文件夹
场景描述 :有时候下载软件会产生很多空的临时文件夹,这个时候手动删除太麻烦,写个程序自动化处理
任务要求:
- 遍历某个指定目录(只遍历第一层即可)
- 判断每一个条目是否是文件夹(不是文件)
- 如果是文件夹,并且这个文件夹是空的(里面没有任何文件或子文件夹),就把它删除
python
import os
folder_dir = r"C:\Users\22330\Desktop\进行中\测试文件夹" # 文件夹路径
for item in os.listdir(folder_dir):
if os.path.isdir(os.path.join(folder_dir, item)): # 如果是文件类型才进行判断
if len(os.listdir(os.path.join(folder_dir, item))) == 0: # 根据枚举的长度判断是否为空文件夹
os.rmdir(os.path.join(folder_dir, item)) # 如果是,则删除
print(f"已删除空文件夹: {item}")
7.3 文件备份
场景描述 :这是一个结合了 "隐藏文件过滤" 和 "复制" 的综合问题。
任务要求:
- 定义一个源目录
source和一个备份目录backup - 将
source里的所有文件复制到backup
关键难点:
- 不要复制隐藏文件(使用刚才学的
stat属性判断) - 不要复制文件夹(只复制文件)
- 复制时要保留文件的修改时间(元数据)
python
import os
import stat
import shutil
folder_dir = r"C:\Users\22330\Desktop\进行中" # 初始文件夹路径
backup_dir = os.path.join(folder_dir, "backup") # 备份文件夹路径
os.makedirs(backup_dir, exist_ok=True) # 备份文件夹
for item in os.listdir(folder_dir):
if os.path.isfile(os.path.join(folder_dir, item)): # 排除文件夹类型
file_stat = os.stat(os.path.join(folder_dir, item)) # 判断是否是隐藏文件
is_hidden = file_stat.st_file_attributes & stat.FILE_ATTRIBUTE_HIDDEN
if not is_hidden: # 如果不是隐藏文件,保留元数据复制
shutil.copy2(os.path.join(folder_dir, item), os.path.join(backup_dir, item))
print(f"已备份: {item}")
掌握代码操作文件系统,是实现自动化的第一步,希望通过上面的讲解,你至少可以实现基本的文件系统操作,我是不懂代码的杰瑞学长,我们下期再见!
如果觉得文章对你有帮助,欢迎点赞 + 收藏 + 关注,一起进步!