我正在尝试使用深度变量进行自然排序来查找下一个文件,但我遇到了一些问题。
文件夹结构如下:
tests/
------test1/
-----------test2/
----------------...
----------------30.jpg
----------------31.jpg
-----------test3/
----------------...
----------------30.jpg
----------------31.jpg
-----------1.jpg
------1.jpg
我想在当前项目之前到达下一个或项目,使用前进和后退功能迭代它们。 获取同一级别的项目当前正在工作,也是为了获得最大深度级别的项目。
例如,我想在
上使用向后功能path=tests/test1/test2/1.jpg
结果
tests/test1/1.jpg
但是
path=tests/test1/test3/1.jpg
结果
tests/test1/test2/31.jpg
显然与前向函数相反的结果相反。 我当前的问题是找到下一级别的下一个文件,而不重复自己并构建一个循环,迭代到目前为止工作完全正常的文件夹,但我现在完全停留在这个。
到目前为止我的当前代码:
import os
import re
import wx
class PathSelect(wx.App):
"""
path select application
"""
def __init__(self):
"""
initializing function
:return:
"""
super(PathSelect, self).__init__()
@staticmethod
def ask_path():
"""
ask for our starting path
:return:
"""
wildcard = ("Image Files (*.*)|*.jpeg;*.jpg;*.png;*.bmp|"
"Joint Photographic Experts Group (*.jpeg;*.jpg)|*.jpeg;*.jpg|"
"Portable Network Graphics (*.png)|*.png|"
"Bitmap (*.bmp)|*.bmp|"
"All files (*.*)|*.*")
dialog = wx.FileDialog(None, "Choose a file", os.getcwd(), "", wildcard, wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
if dialog.ShowModal() == wx.ID_OK:
return dialog.GetPath()
dialog.Destroy()
class PathingAlgorithm(object):
"""
our pathing algorithm
"""
def __init__(self, depth=1):
"""
initializing function
:return:
"""
self.depth = depth
self.image_path = ""
@staticmethod
def natural_sort(current_list):
convert = lambda text: int(text) if text.isdigit() else text.lower()
alphanum_key = lambda key: [convert(c) for c in re.split('([0-9]+)', key)]
return sorted(current_list, key=alphanum_key)
def current(self):
"""
return the current path or ask for the path
:return:
"""
if not self.image_path:
self.image_path = PathSelect.ask_path()
if self.image_path:
return self.image_path
def backward(self, path="", depth=0, ghost=False):
"""
return path for the previous picture
:param path:
:param depth:
:param ghost:
:return:
"""
# max recursion case, break our function here
if self.depth < depth:
return None
depth += 1
if path == "":
path = self.image_path
folder = os.path.dirname(path)
file_name = os.path.basename(path)
folder_content = self.natural_sort(os.listdir(folder))
file_index = folder_content.index(file_name)
if file_index == 0:
path = self.backward(folder, depth, ghost)
# handle max depth case
if path is None:
return None
# get in the same level of the foldertree again if possible
for x in xrange(depth):
path_list = os.listdir(path)
if path_list:
path = os.path.join(path, self.natural_sort(path_list)[len(path_list) - 1])
else:
path = os.path.join(folder, folder_content[folder_content.index(file_name) - 1])
if not ghost:
self.image_path = path
return path
def forward(self, path="", depth=0, ghost=False):
"""
return path for the next picture
:param path:
:param depth:
:return:
"""
depth += 1
# max recursion case, break our function here
if self.depth < depth:
return None
# on start use current path, on recursion skip this
if path == "":
path = self.image_path
folder = os.path.dirname(path)
file_name = os.path.basename(path)
if os.path.isfile(os.path.join(folder, file_name)):
folders = os.listdir(folder)
else:
folders = [name for name in os.listdir(folder) if os.path.isdir(os.path.join(folder, name))]
folder_content = self.natural_sort(folders)
file_index = folder_content.index(file_name)
if file_index == len(folder_content) - 1:
if self.depth - 1 < depth:
files = [name for name in os.listdir(folder) if os.path.isfile(os.path.join(folder, name))]
if files:
return os.path.join(folder, files[0])
path = self.forward(folder, depth, ghost)
# handle max depth case
if path is None:
return None
# get in the same level of the foldertree again if possible
for x in xrange(depth):
if not os.path.isfile(path):
file_list = os.listdir(path)
if file_list:
path = os.path.join(path, self.natural_sort(file_list)[0])
else:
path = os.path.join(folder, folder_content[folder_content.index(file_name) + 1])
if not ghost:
self.image_path = path
return path
if __name__ == "__main__":
app = wx.App()
app.MainLoop()
ps = PathingAlgorithm(depth=3)
# print ps.current()
# print ps.backward(ghost=True)
# print ps.forward(ghost=True)
print ps.forward(
path='../tests/test1/test2/31.jpg',
ghost=True,
)
感谢您提前提供任何帮助
答案 0 :(得分:1)
我太专注于递归函数,在排序的文件树上解决它是解决方案,目前不是最好的性能是深度太大而且它想要获取所有文件,但对我的情况来说足够好
def get_file_tree(self, path):
"""
return a natural sorted file tree and the index of your original file
:param path:
:return:
"""
if not os.path.exists(path):
return None
filename = os.path.basename(path)
basepath = os.path.abspath(os.path.dirname(path))
for _ in xrange(self.depth):
path = os.path.abspath(os.path.join(basepath, os.pardir))
# list all files
configfiles = [os.path.join(dirpath, f)
for dirpath, dirnames, files in os.walk(path)
for f in fnmatch.filter(files, '*')]
# use natural sort for the tree
configfiles = self.natural_sort(configfiles)
original_path = os.path.join(basepath, filename)
original_index = configfiles.index(original_path)
return configfiles, original_index
def backward(self, path="", ghost=False):
"""
get the next file of our current or defined path
:param path:
:param ghost:
:return:
"""
if path == "":
path = self.image_path
path = os.path.abspath(path)
configfiles, original_index = self.get_file_tree(path)
# if file was non existant or the index was 0 return None
if original_index is None or original_index == 0:
return None
new_path = configfiles[original_index - 1]
if new_path.count("\\") > path.count("\\"):
return None
if not ghost:
self.image_path = new_path
return new_path
def forward(self, path="", ghost=False):
"""
get the next file of our current or defined path
:param path:
:param ghost:
:return:
"""
if path == "":
path = self.image_path
path = os.path.abspath(path)
configfiles, original_index = self.get_file_tree(path)
# if file was non existant or was the last file, return None
if original_index is None or len(configfiles) <= original_index + 1:
return None
new_path = configfiles[original_index + 1]
if not ghost:
self.image_path = new_path
return new_path