为了账号安全,请及时绑定邮箱和手机立即绑定

重命名文件夹和文件,而 os.walk() 更改目录名称后丢失了一些文件

重命名文件夹和文件,而 os.walk() 更改目录名称后丢失了一些文件

慕田峪7331174 2021-08-05 18:21:06
我有一个这样的文件夹结构:Template  - Template1  - Template2TemplateTest  - TemplateTest1Config  - TemplateConfig我想将每个文件名和每个文件夹名的“模板”替换为“MyApp”。这是我的代码:for root, dirs, files in os.walk(path):    for name in files:        if name.startswith("Template"):            replace = name.replace("Template",'MyApp')            os.rename(os.path.join(root,name),os.path.join(root,name.replace(old,new)))    for name in dirs:        if name.startswith("Template"):            replace = name.replace("Template",'MyApp')            os.rename(os.path.join(root,name),os.path.join(root,replace))奇怪的是,这只替换了文件夹名称,而父文件夹名称的文件名不需要更改。像这样:MyApp  - Template1  - Template2MyAppTest  - TemplateTest1Config  - MyAppConfig但如果我执行此代码两次,那么它将替换文件。我想知道为什么以及如何更改代码以替换我需要的所有内容?
查看完整描述

2 回答

?
PIPIONE

TA贡献1829条经验 获得超9个赞

(请注意,调用签名为os.walk:


os.walk = walk(top, topdown=True, onerror=None, followlinks=False)

所以你正在通过True, None, 和False.)


问题与os.walk遍历目录和文件的顺序以及它进入哪些目录和文件有关。


特别是,它首先读取位于 的目录path。这会产生以下结果:


['Template', 'TemplateTest', 'Config']

所有这些都是目录,因此它下次将遍历的子目录列表是相同的,并且没有文件。这在第一次迭代中作为三个值返回:


path

['Template', 'TemplateTest', 'Config']

[]

然后,您执行自己的代码,在其中调用os.renameon Template,以便现在将其命名为MyApp,然后调用on ,以便现在TemplateTest将目录命名为MyAppTest。


接下来,os.walk代码尝试读取子目录Template。这失败了,所以什么也没有发生(onerror是None)。


接下来,os.walk代码尝试读取子目录TemplateTest。这失败了,所以什么也没有发生。


最后,os.walk代码尝试读取子目录Config。这成功了,一切顺利。


有两种不同的解决方案:您可以设置topdown为False,或者您可以更新已命名的列表,dirs以便os.walk知道目录的新名称。(编辑:我不确定topdown=False会修复它;这需要测试。)


查看完整回答
反对 回复 2021-08-05
  • 2 回答
  • 0 关注
  • 325 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号