Python实现文件管理系统
狂码了一天,各种修改优化,最后决定就这样,其实最开始就只打算能批量重命名一下图片就ok的
下面是代码实现部分,注释还是比较清楚的
代码实现
import os # 操作系统库
import re # 正则表达式库
import sys # 系统库
import shutil # 删除目录
from colorama import init, Fore, Back, Style # 改变输出文字颜色
# 菜单类
class Menu:
def __init__(self):
self.rename = Rename()
self.delete = Delete()
self.choices = {
"1": self.rename.run1,
"2": self.delete.run2,
"3": self.quit
} # 定义包含序号和操作的字典
def show_menu(self):
print(Fore.LIGHTRED_EX + "*****欢迎来到Xherlock的文件管理系统*****")
print(Fore.LIGHTRED_EX + " (1) 重命名")
print(Fore.LIGHTRED_EX + " (2) 删除")
print(Fore.LIGHTRED_EX + " (3) 退出")
def run(self):
while True:
self.show_menu()
try:
choice = input("请输入你的选择(数字)")
except Exception as e:
print("请输入有效选项!")
continue
choice = str(choice).strip() # 分割空白符和回车符
action = self.choices.get(choice) # 获取选择的操作
if action:
action()
else:
print("没有{0}这个选项!请重新选择".format(choice))
def quit(self):
print(Fore.LIGHTBLUE_EX + "感谢您使用Xherlock的文件管理系统!")
sys.exit(0)
# 重命名类
class Rename:
def __init__(self):
self.choices = {
"1": self.rename_file,
"2": self.rename_files,
"3": " "
}
def show_rename_menu(self):
print(Fore.LIGHTYELLOW_EX + "*****重命名*****")
print(Fore.LIGHTYELLOW_EX + " (1) 单个")
print(Fore.LIGHTYELLOW_EX + " (2) 批量")
print(Fore.LIGHTYELLOW_EX + " (3) 退出")
def run1(self):
while True:
self.show_rename_menu()
try:
choice1 = input("请输入你的选择(数字)")
except Exception as e:
print("请输入有效选项!")
print("---------------------------------------------------")
continue
choice1 = str(choice1).strip()
action = self.choices.get(choice1)
if action:
if choice1 == "3":
break
action()
else:
print("没有{0}这个选项!请重新选择".format(choice1))
def rename_file(self):
"""
重命名单个文件:
输入所要重命名文件所在目录的绝对路径,展示列表后选择相应序号进行重命名
依次输入新名字,判断是否要修改后缀名(后缀名不得包含非法字符),若需要修改后缀名,需要输入新后缀名
最后展示修改前后的文件列表,对比可以看出所作的更改
中间在重命名后会进行判断新名字是否已存在,若存在返回重新尝试的提醒
"""
try:
path = input("请输入重命名文件路径:")
currentpath = os.getcwd() # 得到当前工作目录
os.chdir(path) # 将当前工作目录修改为待修改文件所在目录
filelist = os.listdir(path) # 获取目录下的文件列表
i = 1 # 初始化计数器
print(">>>文件列表")
for filename in filelist:
print(f"[{i}] {filename}") # 输出文件列表
i += 1
print(Fore.LIGHTRED_EX + "!建议重命名文件而不是文件夹")
num = input("请输入你要修改文件的序号:") # 输入选择重命名的文件序号
name = os.path.splitext(filelist[int(num) - 1])
suffix = name[1] # 使用os库下的函数分割文件名来获取后缀名,正则表达式有点麻烦
new_name = input("请输入新文件名:")
change_suffix = input("是否要修改后缀名(y/n):")
if change_suffix == 'y' or change_suffix == 'Y':
new_suffix = input("请输入新的后缀名(不得包含'?\ * | “ < > : /'):")
print("修改前:" + str(os.listdir(path)))
os.rename(filelist[int(num) - 1], (str(new_name) + '.' + new_suffix))
elif change_suffix == 'n' or change_suffix == 'N':
print("修改前:" + str(os.listdir(path)))
os.rename(filelist[int(num) - 1], (str(new_name) + suffix))
else:
print("输入错误!")
return
print("---------------------------------------------------")
os.chdir(currentpath) # 改回程序运行前的工作目录
sys.stdin.flush() # 刷新
print("修改后:" + str(os.listdir(path))) # 输出修改后文件夹中包含的文件
except FileExistsError as e: # 抛出重命名文件已存在的错误
print("文件已存在,请重新尝试命名!")
def rename_files(self):
"""
批量重命名文件:
输入所要批量重命名文件所在目录的绝对路径,先选择是否自定义批量修改
在自定义批量修改模式下会先展示目录下的全部文件及其序号,然后输入想要重命名文件的序号(以英文逗号分隔)
然后依次询问是否统一修改后缀名,是否自定义name+自动化数字,若不统一修改后缀名,则必须为图片格式
若未选择该模式,就是按1-n命名
依次输入新名字,判断是否要修改后缀名(后缀名不得包含非法字符),若需要修改后缀名,需要输入新后缀名
最后展示修改前后的文件列表,对比可以看出所作的更改
中间在重命名后会进行判断新名字是否已存在,若存在返回重新尝试的提醒
"""
try:
print("---------------------------------------------------")
print(Fore.LIGHTRED_EX + "!建议批量修改的文件为同一类型格式,比如全是图片或word文档")
path = input("请输入批量重命名文件的路径:")
currentpath = os.getcwd() # 得到进程当前工作目录
os.chdir(path) # 将当前工作目录修改为待修改文件夹的位置
filelist = os.listdir(path)
print("<自定义批量修改模式>:依据序号选择想要重命名的文件")
flag0 = input("是否进入自定义批量修改模式(y/n):")
if flag0 == 'y' or flag0 == 'Y': # 自定义模式重命名
num = 1
print("文件列表>>>")
for filename in filelist:
print(f"[{num}] {filename}")
num += 1
num = input("请输入你要修改文件的序号(以逗号分隔):")
numlist = num.split(',')
flag1 = input("是否统一修改后缀名(y/n):")
if flag1 == 'y' or flag1 == 'Y':
new_suffix = input("请输入新的后缀名(不得包含'?\ * | “ < > : /'):")
flag2 = input("是否自定义文件名(y/n):")
if flag2 == 'y' or flag2 == 'Y':
new_name = input("请输入新的文件名:")
print("修改前:" + str(os.listdir(path)))
i = 0
for j in numlist:
i += 1
if flag1 == 'y' or flag1 == 'Y':
if flag2 == 'y' or flag2 == 'Y':
os.rename(filelist[int(j) - 1], (str(new_name) + str(i) + '.' + str(new_suffix)))
elif flag2 == 'n' or flag2 == 'N':
os.rename(filelist[int(j) - 1], (str(i) + '.' + str(new_suffix)))
else:
print("输入错误!")
return
elif flag1 == 'n' or flag1 == 'N':
pat = ".+\.(jpeg|jpg|png|gif|bmp)" # 匹配文件名正则表达式
pattern = re.findall(pat, filelist[int(j) - 1]) # 进行匹配
if flag2 == 'y' or flag2 == 'Y':
os.rename(filelist[int(j) - 1], (str(new_name) + str(i) + '.' + pattern[0]))
elif flag2 == 'n' or flag2 == 'N':
os.rename(filelist[int(j) - 1], (str(i) + '.' + pattern[0]))
else:
print("输入错误!")
return
else:
print("输入错误!")
return
elif flag0 == 'n' or flag0 == 'N': # 非自定义模式重命名
k = 1
print("修改前:" + str(os.listdir(path)))
for file in filelist:
name = os.path.splitext(filelist[int(k) - 1])
suffix = name[1]
os.rename(filelist[int(k) - 1], (str(k) + suffix))
k += 1
else:
print("输入错误!")
return
print("---------------------------------------------------")
os.chdir(currentpath) # 改回程序运行前的工作目录
sys.stdin.flush() # 刷新
print("修改后:" + str(os.listdir(path))) # 输出修改后文件夹中包含的文件
except FileExistsError as e:
print("文件已存在,请重新尝试!")
class Delete:
def __init__(self):
self.choices = {
"1": self.del_folder,
"2": self.del_file,
"3": " "
}
def show_del_menu(self):
print(Fore.LIGHTGREEN_EX + "*****删除*****")
print(Fore.LIGHTGREEN_EX + " (1) 文件夹")
print(Fore.LIGHTGREEN_EX + " (2) 文件")
print(Fore.LIGHTGREEN_EX + " (3) 退出")
def run2(self):
while True:
self.show_del_menu()
try:
choice2 = input("请输入你的选择(数字)")
except Exception as e:
print("请输入有效选项!")
print("---------------------------------------------------")
continue
choice2 = str(choice2).strip()
action = self.choices.get(choice2)
if action:
if choice2 == "3":
break
action()
else:
print("没有{0}这个选项!请重新选择".format(choice2))
def del_folder(self):
"""
删除文件夹
"""
print("---------------------------------------------------")
path = input("请输入删除文件夹的路径:")
confirm = input("确认是否删除(y/n):")
if confirm == 'y' or confirm == 'Y':
if os.path.exists(path):
shutil.rmtree(path) # 必须得使用shutil库里的方法,os库没有权限删除目录
print("删除成功!")
else:
print("文件夹不存在!")
else:
print("‘三思而后行’这句话很对")
return
def del_file(self):
"""
删除文件:
可以选择是删除一个还是多个文件
"""
print("---------------------------------------------------")
path = input("请输入删除文件所在目录:")
filelist = os.listdir(path)
i = 1
print(">>>文件列表")
for file in filelist:
print(f'[{i}]{file}')
i += 1
choice = input("删除一个(y)或多个(n)文件(y/n):")
if choice == 'y' or choice == 'Y':
num = input("请输入你要删除文件的序号:")
confirm = input("确认是否删除(y/n):")
if confirm == 'y' or confirm == 'Y':
new_path = path + '\\' + filelist[int(num) - 1]
os.remove(new_path)
print("删除成功!")
elif confirm == 'n' or confirm == 'N':
print("‘三思而后行’这句话很对")
return
else:
print("输入错误!")
elif choice == 'n' or choice == 'N':
try:
num = input("请输入你要删除文件的序号(用逗号分隔):")
numlist = num.split(',')
confirm = input("确认是否删除(y/n):")
if confirm == 'y' or confirm == 'Y':
for i in numlist:
new_path = path + '\\' + filelist[int(i) - 1]
os.remove(new_path)
print("删除成功!")
elif confirm == 'n' or confirm == 'N':
print("‘三思而后行’这句话很对")
return
else:
print("输入错误!")
except ValueError as e:
print("输入序号错误!请重新操作")
else:
print("输入错误!")
if __name__ == '__main__':
init(autoreset=True)
# ASCII字符签名,好看而已
print(Fore.LIGHTMAGENTA_EX + "___ ___ __ __ _______ .______ __ ______ ______ __ ___")
print(Fore.LIGHTMAGENTA_EX + "\ \ / / | | | | | ____|| _ \ | | / __ \ / || |/ /")
print(Fore.LIGHTMAGENTA_EX + " \ V / | |__| | | |__ | |_) | | | | | | | | ,----'| ' / ")
print(Fore.LIGHTMAGENTA_EX + " > < | __ | | __| | / | | | | | | | | | < ")
print(Fore.LIGHTMAGENTA_EX + " / . \ | | | | | |____ | |\ \----.| `----.| `--' | | `----.| . \ ")
print(Fore.LIGHTMAGENTA_EX + "/__/ \__\ |__| |__| |_______|| _| `._____||_______| \______/ \______||__|\__\\")
Menu().run()
部分效果展示
单个重命名
批量重命名
删除
不展示了,这玩意还是自己用文件资源管理器吧,用不好删掉了,回收站里都找不到ಥ_ಥ
写出来纯粹是用来练习的
总结
这次完成这个小项目也学习到了不少
- python利用相关库操作文件(重命名和删除)
- 掌握了写项目的一点门道:如主函数和类的开发、相应错误的抛出(这比我上学期学java学的还更深刻,属实是Java没咋学会)
- 新见识了ASCII的艺术签名
当然没有完全按照最初的思维导图设计那样,比如省略了判断文件和文件夹是否存在,感觉没必要了