我编写了一个函数,用于将文件从目录A复制到目录B递归。 代码是这样的:
import os
import shutil
import sys
from os.path import join, exists
def copy_file(src, dest):
for path, dirs, files in os.walk(src, topdown=True):
if len(dirs) > 0:
for di in dirs:
copy_file(join(path, di), join(dest, di))
if not exists(dest):
os.makedirs(dest)
for fi in files:
shutil.copy(join(path, fi), dest)
在我的测试中,输入参数是这样的:
src = d:/dev
它有一个名为py
的子目录。此外,py
有一个名为test
dest = d:/dev_bak
所以,当我测试我的代码时,发生了一些奇怪的事情。
在我的dest
目录d:/dev_bak
中,创建了三个子目录。
那就是:d:/dev_bak/py
; d:/dev_bak/py/test
; d:/dev_bak/test
。
在我的设计中,dev_bak
的结构与dev
相同。那么,为什么会这样呢!
答案 0 :(得分:2)
您可以通过
轻松诊断出来 print path, dirs, files
正下方
for path, dirs, files in os.walk(src, topdown=True):
基本上,你要两次递归。
本身,os.walk
下降到子目录中。你通过递归调用自己的函数来双下降。以下是print
语句的一些示例输出:
>>> copy_file("c:\Intel", "c:\Intel-Bak") c:\Intel ['ExtremeGraphics', 'Logs'] [] c:\Intel\ExtremeGraphics ['CUI'] [] c:\Intel\ExtremeGraphics\CUI ['Resource'] [] c:\Intel\ExtremeGraphics\CUI\Resource [] ['Intel\xae Graphics and Media Control Panel.lnk', 'Intel\xae HD Graphics.lnk'] c:\Intel\ExtremeGraphics\CUI\Resource [] ['Intel\xae Graphics and Media Control Panel.lnk', 'Intel\xae HD Graphics.lnk'] c:\Intel\ExtremeGraphics\CUI ['Resource'] [] c:\Intel\ExtremeGraphics\CUI\Resource [] ['Intel\xae Graphics and Media Control Panel.lnk', 'Intel\xae HD Graphics.lnk'] c:\Intel\ExtremeGraphics\CUI\Resource [] ['Intel\xae Graphics and Media Control Panel.lnk', 'Intel\xae HD Graphics.lnk'] c:\Intel\Logs [] ['IntelChipset.log', 'IntelControlCenter.log', 'IntelGFX.log', 'IntelGFXCoin.log'] c:\Intel\ExtremeGraphics ['CUI'] [] c:\Intel\ExtremeGraphics\CUI ['Resource'] [] c:\Intel\ExtremeGraphics\CUI\Resource [] ['Intel\xae Graphics and Media Control Panel.lnk', 'Intel\xae HD Graphics.lnk'] c:\Intel\ExtremeGraphics\CUI\Resource [] ['Intel\xae Graphics and Media Control Panel.lnk', 'Intel\xae HD Graphics.lnk'] c:\Intel\ExtremeGraphics\CUI ['Resource'] [] c:\Intel\ExtremeGraphics\CUI\Resource [] ['Intel\xae Graphics and Media Control Panel.lnk', 'Intel\xae HD Graphics.lnk'] c:\Intel\ExtremeGraphics\CUI\Resource [] ['Intel\xae Graphics and Media Control Panel.lnk', 'Intel\xae HD Graphics.lnk'] c:\Intel\Logs [] ['IntelChipset.log', 'IntelControlCenter.log', 'IntelGFX.log', 'IntelGFXCoin.log']
如您所见,目录被访问了两次。
你应该修改程序的逻辑,这样它只访问每个目录一次,但理论上你可以忽略你去过的任何目录:
visited = []
def copy_file(src, dest):
for path, dirs, files in os.walk(src, topdown=True):
if path not in visited:
for di in dirs:
print dest, di
copy_file(join(path, di), join(dest, di))
if not exists(dest):
os.makedirs(dest)
for fi in files:
shutil.copy(join(path, fi), dest)
visited.append(path)
答案 1 :(得分:0)
shutil模块已经有一个copytree函数,它将递归复制目录。您可能希望使用它而不是提供自己的实现。