实现递归时遇到问题

Having issue while implementing recursion

考虑到目标目录与源目录具有相同的文件和文件夹结构,我正在尝试将文件从一个源目录移动到另一个目标目录。

源码目录:

source/
├── file1
├── file2
├── file3
├── folder_a
└── folder_b
    ├── file1
    ├── file2
    └── file3

目标目录:

destination/
├── file4
├── file5
├── file6
├── folder_a
└── folder_b
    ├── file4
    ├── file5
    └── file6

我正在尝试创建的脚本:

import os
import shutil
from subprocess import check_output

os.chdir("/home/smetro/source/")
destination= "/home/smetro/Games/destination"
def mover(destination):
    for i in os.listdir():
        if os.path.isfile(i):
            shutil.copy(i,destination)
            print("file moved: {} to {}".format(i,destination))
        else:
            new_dir= check_output('pwd').strip().decode('utf-8')+"/"+i
            os.chdir(new_dir)
            destination += "/{}".format(i)
            mover(destination)
            
mover(destination)

只要我是 运行 脚本,我就可以将一些文件从源目录移动到目标目录。但是,它抛出 FileNotFoundError 错误,我得到如下所述的输出:

file moved: file1 to /home/smetro/Games/destination
file moved: file3 to /home/smetro/Games/destination
file moved: file2 to /home/smetro/Games/destination
file moved: file1 to /home/smetro/Games/destination/folder_b
file moved: file3 to /home/smetro/Games/destination/folder_b
file moved: file2 to /home/smetro/Games/destination/folder_b
Traceback (most recent call last):
  File "/home/smetro/move.py", line 18, in <module>
    mover(destination)
  File "/home/smetro/move.py", line 14, in mover
    os.chdir(new_dir)
FileNotFoundError: [Errno 2] No such file or directory: '/home/smetro/source/folder_b/folder_a'

我不确定我是否以错误的方式使用了递归或者无法正确使用 OS 模块。任何帮助将不胜感激。

这个问题与递归无关。回溯显示错误没有发生在递归调用中。它也与 os 模块无关。

最好的提示是不存在目录的路径:folder_b/folder_a。问题是您正在循环 os.listdir(),但在循环中更改工作目录,因此在 cd-ing 到 folder_b 之后,它会尝试 cd 到 folder_a,这是' t 在 folder_b.

我可以想出几种不同的方法来解决这个问题,但最好不要更改工作目录。相反,使用 os.walk() to walk the directory branch for you, as well as pathlib 来简化对路径的处理。入门指南:

from pathlib import Path

source = Path("/home/smetro/source/")
destination = Path("/home/smetro/Games/destination")
for root, _dirs, files in os.walk(source):
    root_rel = Path(root).relative_to(source)
    new_root = destination / root_rel
    for file in files:
        print(new_root / file)  # Just for demo