これは、次のように簡単に診断できます
print path, dirs, files
真下
for path, dirs, files in os.walk(src, topdown=True):
基本的に、2回再帰しています。
それ自体で、os.walk
サブディレクトリに降ります。独自の関数を再帰的に呼び出すことで、二重降下しています。print
そのステートメントからの出力例を次に示します。
>>> copy_file("c:\Intel", "c:\Intel-Bak")
c:\Intel ['ExtremeGraphics', 'ログ'] []
c:\Intel\ExtremeGraphics ['CUI'] []
c:\Intel\ExtremeGraphics\CUI ['リソース'] []
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 ['リソース'] []
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 ['リソース'] []
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 ['リソース'] []
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']
ご覧のとおり、ディレクトリは 2 回アクセスされます。
プログラムのロジックを修正して、各ディレクトリに一度だけアクセスするようにする必要がありますが、理論的には、既にアクセスしたディレクトリは無視できます。
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)