我有一个这样的文件夹结构:
Template
- Template1
- Template2
TemplateTest
- TemplateTest1
Config
- TemplateConfig
我想将每个文件名和每个文件夹名称的“Template”替换为“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
- Template2
MyAppTest
- TemplateTest1
Config
- MyAppConfig
但是如果我执行此代码两次,它将替换这些文件。 我想知道为什么以及如何更改代码,以便它取代我需要的一切?
最佳答案
(请注意 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.rename
上Template
,因此现在将其命名为 MyApp
,然后TemplateTest
,因此该目录现在名为 MyAppTest
.
接下来,os.walk
代码尝试读取子目录 Template
。此操作失败,因此什么也没有发生( onerror
是 None
)。
接下来,os.walk
代码尝试读取子目录 TemplateTest
。这失败了,所以什么也没有发生。
最后,os.walk
代码尝试读取子目录 Config
。这次成功了,一切顺利。
有两种不同的解决方案:您可以设置 topdown
至False
,或者您可以更新名为 dirs
的列表这样os.walk
知道目录的新名称。 (编辑:我不确定 topdown=False
是否会修复它;这需要测试。)
(编辑:topdown=False
确实会修复它。文档中对此进行了描述:
When topdown is True, the caller can modify the dirnames list in-place (perhaps using del or slice assignment), and walk() will only recurse into the subdirectories whose names remain in dirnames; this can be used to prune the search, impose a specific order of visiting, or even to inform walk() about directories the caller creates or renames before it resumes walk() again. Modifying dirnames when topdown is False has no effect on the behavior of the walk, because in bottom-up mode the directories in dirnames are generated before dirpath itself is generated.
)
关于python - 在 os.walk() 更改目录名称后重命名文件夹和文件时丢失了一些文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53123867/