基本的内容
使用 python os.walk()
方法,将指定文件夹中的所有文件和文件夹信息读出,并以dict字典的形式存储在变量中。
这里制定的规则为:当函数遇到文件夹就将其做为字典元素(文件夹名: {}
)插入到汇总的字典中,遇到文件就将其做为文本元素(文件名:文件路径
)插入到汇总的字典中,对目标文件夹一层一层递归直到所有文件夹和文件均被处理完毕。预期所生成的dict字典的详细结构如下所示:
{'目标文件夹':{
'学习资料':{
'js基础知识': "c:/...../..../...",
'python相关': {
'python基础知识': "c:/...../..../...",
'python自动化': "c:/...../..../..."
}
},
'娱乐':{
'使用文本文件': "c:/...../..../...",
'游戏': {
'英雄联盟': {
'xxx文件': : "c:/...../..../...",
'xxx文件': : "c:/...../..../...",
'xxx文件': : "c:/...../..../...",
}
'使命召唤': {
'音频': {
'xxx文件': : "c:/...../..../...",
'xxx文件': : "c:/...../..../...",
'xxx文件': : "c:/...../..../...",
}
'xxx文件': : "c:/...../..../...",
'xxx文件': : "c:/...../..../...",
'xxx文件': : "c:/...../..../...",
}
'游戏菜单: "c:/...../..../..."
}
}
}}
这里主要的核心逻辑就是运用python变量的内存地址特性来实现字典数据的灵活写入,多余的废话就不再赘述,直接附上代码:
hierarchy = {} # 数据汇总字典
def _get_img_info(data_dir):
"""
获取指定文件夹的目录信息,并生成对应的目录结构数据
参数:
@param data_dir : 指定的“用例步骤”文件夹路径
"""
parent = data_dir.split('\\')[-2] # 父级目录取出
keyRoute = {}
objectData = hierarchy # 指向
for root, dirs, files in os.walk(data_dir, topdown=True):
detailRoute = [] # 置空
root = format(root); dirs = eval(format(dirs)); files = eval(format(files))
key_id = root.split('\\')[-1]
'''字典路由生成'''
rootList = re.findall(f'{parent}\\\(.+)', root)
detailRoute = "".join(rootList).split('\\')
'''路由进入'''
try:
for value in keyRoute[key_id]: objectData = objectData[value]
objectData = objectData[key_id]
except Exception as error:
objectData.setdefault(key_id, {})
objectData = objectData[key_id]
'''文件夹处理'''
if dirs:
for folder in dirs:
objectData.setdefault(folder, {})
keyRoute[folder] = detailRoute
'''文件处理'''
if files: # 你可以在这里做一些限制,比如过滤掉某种类型的文件
# for file in [item for item in files if ('xlsx' in item.split('.') or 'xls' in item.split('.'))]: # 移除非excel工作簿文件
for file in [item for item in files]: objectData[file] = root + '\\' + file
'''本级循环结束'''
objectData = hierarchy # 还原
if __name__ == '__main__':
_get_img_info(r"xxxxx") # 输入目标文件夹路径
print(hierarchy)
给一个简单的文件夹结构
执行函数,运行结果如下:
'''
{
'测试文件夹': {
'娱乐': {
'使命召唤': {
'bin': {
'my.ini': 'D:\\测试文件夹\\娱乐\\使命召唤\\bin\\my.ini'
},
'lib': {
'lib.txt': 'D:\\测试文件夹\\娱乐\\使命召唤\\lib\\lib.txt'
}
},
'英雄联盟': {
'bin': {
'my.ini': 'D:\\测试文件夹\\娱乐\\英雄联盟\\bin\\my.ini'
},
'LOL.exe': 'D:\\测试文件夹\\娱乐\\英雄联盟\\LOL.exe'
},
'音乐1.txt': 'D:\\测试文件夹\\娱乐\\音乐1.txt'
},
'学习': {
'javaScript相关': {
'基础知识': {
'分支结构.txt': 'D:\\测试文件夹\\学习\\javaScript相关\\基础知识\\分支结构.txt',
'数据类型.txt': 'D:\\测试文件夹\\学习\\javaScript相关\\基础知识\\数据类型.txt',
'表达式.txt': 'D:\\测试文件夹\\学习\\javaScript相关\\基础知识\\表达式.txt',
'运算符.txt': 'D:\\测试文件夹\\学习\\javaScript相关\\基础知识\\运算符.txt'
},
'进阶知识': {}
},
'python基础.txt': 'D:\\测试文件夹\\学习\\python基础.txt',
'python进阶.txt': 'D:\\测试文件夹\\学习\\python进阶.txt'
},
'工作报告.docx': 'D:\\测试文件夹\\工作报告.docx',
'数据报表.xlsx': 'D:\\测试文件夹\\数据报表.xlsx'
}
}
'''
与elementUI中的 Tree树形控件联用
写到这里我突然萌生了一个比较有意思的想法,就是能不能将这个函数和 elementUI中的 Tree树形控件一起联用,来实现一个简单的目录文件选择工具。
其实这个想法还是很好实现的,只不过就是按照Tree树形控件的数据要求把我们制定的字典数据格式修改一下就好。Tree树形控件的数据要求是这样的[{id:1, label:'xx', children: [{}]}, {id:2, label:'xx'}...]
(这些都可以在 elementUI的官方文档中找到),可以简单的理解为遇到文件夹就采用 {id:1, label:'xx', children: [{}]}
的形式书写,遇到文件就采用 {id:2, label:'xx'}
的形式书写,理清楚思路后就直接上手改代码。
def get_hierarchy(folderSrc, hierarchy):
"""
获取指定文件夹的目录信息,并生成对应的目录结构数据
参数:
@param folderSrc : 指定的“用例步骤”文件夹路径
@param hierarchy : 目录结构结果数组, 此处传入空数组 [] 即可
"""
objectData = hierarchy # 指向
indexRoute = {} # 数组索引关系路由
for root, dirs, files in os.walk(folderSrc, topdown=True):
# 如果想要过滤掉一些文件夹可以对 dirs做操作。
root = format(root); files = eval(format(files))
detailRoute = [] # 置空
key_id = "\\".join(root.split('\\'))
'''路由进入'''
try:
for index in indexRoute[key_id]:
objectData = objectData[index]['children']
detailRoute = indexRoute[key_id]
except Exception as error:
title = key_id.split("\\")[-1]
objectData.append({'id': title, 'label': title, 'children': []});
objectData = objectData[0]['children']
detailRoute = [0]
'''文件夹处理'''
if dirs:
for num, folder in enumerate(dirs):
tran_Route = [item for item in detailRoute]
if os.listdir(root + '\\' + folder):
objectData.append({'id': folder, 'label': folder, 'children': []})
else:
'''文件夹为空不可操作'''
objectData.append({'id': folder, 'label': folder, 'children': [], 'disabled': True}) # 这里的True在js中要书写为true
tran_Route.append(num)
tran_folder = "\\".join(root.split('\\')) + "\\" + folder;
indexRoute[tran_folder] = tran_Route
'''文件处理'''
if files:
for file in [item for item in files]: # 你可以在这里加一些限制来过滤掉某个类型的文件
objectData.append({'id': file, 'label': file})
'''本级循环结束'''
objectData = hierarchy # 还原
return hierarchy
if __name__ == '__main__':
print(get_hierarchy(r"xxxxx", []))
最后处理后的数据如下图所示
''' # 这里只书写了一部分,全写下来太多了
[
{
'id': '测试文件夹',
'label': '测试文件夹', 'children': [
{
'id': '娱乐',
'label': '娱乐',
'children': [
{
'id': '使命召唤',
'label': '使命召唤',
'children': [
{
'id': 'bin',
'label': 'bin',
'children': [
{'id': 'my.ini', 'label': 'my.ini'}
]
},
{
'id': 'lib',
'label': 'lib',
'children': [
{'id': 'lib.txt', 'label': 'lib.txt'}
]
}
]
},
{
'id': '英雄联盟',
'label': '英雄联盟',
'children': [
{
'id': 'bin',
'label': 'bin',
'children': [
{'id': 'my.ini', 'label': 'my.ini'}
]
},
{'id': 'LOL.exe', 'label': 'LOL.exe'}
]
},
{'id': '音乐1.txt', 'label': '音乐1.txt'}
]
}
]
}
]
'''
将得到的数据赋值给Tree树形控件,效果图如下所示:
文章撰写的比较潦草,例子中还有很多值得优化的地方,各位可以根据自己的习惯对其进行优化,不过文章的本意还是给大家提供一个思路,希望对各位有所帮助。