【发布时间】:2015-07-20 21:30:52
【问题描述】:
我以为我已经弄清楚了 - “是的!最后,我成功地使用了递归函数 - 是的......哦哦不”
我有一本包含文件夹和文件的文件结构数据的字典:
{
"FOLDER_NAME": {
type: "dir",
children: {
"FOLDER_NAME": {
type: "dir",
children: { ... }
},
"FILE_NAME": {
type: "file",
url: '...'
},
"FILE_NAME": {
type: "file",
url: '...'
}
}
}
我编写了以下递归函数来获取任何元素,只要它是一个目录,我想处理该目录的所有内容,只要目录中有一个目录,我想先处理该目录,所以上。
对process_dir 的初始调用使用dir_name="/root/path",dir_content 是上面的sn-p 和first = True。
def process_dir(dir_name, dir_content, first):
global download_path
if first:
download_path = dir_name + '/'
else:
download_path += clean_path(dir_name) + '/'
full_path = download_path
if not os.path.exists(full_path):
os.makedirs(full_path)
for x in dir_content:
type = dir_content[x]['type']
if type == 'dir':
process_dir(x, dir_content[x]['children'], False)
elif type == 'file':
download_file(x, dir_content[x]['size'], dir_content[x]['url'])
这应该按预期工作吗?至少对我来说它没有按预期工作,因为它没有按顺序遍历字典中的每个节点。
在处理完某个目录的内容后,如何检测到它并返回到对该目录的process_dir 的原始调用,以便我可以从full_path 中删除最后一个子目录部分?
在 Javeed 的回答的帮助下,我能够解决我的问题,导致以下修改后的代码 sn-p:
def process_dir(path, new_name, dir_content):
if not dir_content:
return None
new_path = path + '/' + new_name
if not os.path.exists(new_path):
os.makedirs(new_path)
for x in dir_content:
type = dir_content[x]['type']
if type == 'dir':
process_dir(new_path, clean_path(x), dir_content[x]['children'])
elif type == 'file':
download_file(new_path + '/' + clean_path(x), dir_content[x]['size'], dir_content[x]['url'])
【问题讨论】:
-
“应该按预期工作吗?”如果您告诉我们它是否适合您,会更容易。不过有一些通用提示:您应该能够避免使用
global download_path,并使用os.path.join连接路径名的各个部分。您可以通过调用process_dir(os.path.join(dir_name, x), ...)来同时执行这两项操作(然后您也可以省略first参数)。 -
@Evert
first参数与初始调用有关,因为我的clean_path函数将去除除数,并且只能按单个目录或文件名调用。我可以摆脱全局download_path是的,谢谢。 -
os.path.join不关心路径分隔符,因此无需手动删除并重新添加。例如os.path.join('/home', 'evert', 'Documents/', 'somefile.txt')导致'/home/evert/Documents/somefile.txt':无需手动删除或附加'/'。事实上,如果你喜欢平台兼容,os.path.join会考虑路径分隔符的差异(例如 Windows 上的 `\`)。
标签: python python-2.7 dictionary recursion