在Python中递归复制文件或目录

157 投票
6 回答
228115 浏览
提问于 2025-04-15 17:34

在Python中,确实有一些函数可以用来复制文件,比如 shutil.copy,还有一些函数可以用来复制文件夹,比如 shutil.copytree。不过,我没有找到一个可以同时处理这两者的函数。虽然判断你要复制的是文件还是文件夹其实很简单,但这个缺失还是让人觉得有点奇怪。

难道真的没有一个标准的函数,像Unix系统中的 cp -r 命令那样,既能支持文件也能支持文件夹,并且可以递归地复制吗?在Python中,有什么优雅的办法来解决这个问题呢?

6 个回答

6

shutil.copyshutil.copy2 是用来复制文件的。

shutil.copytree 则是用来复制一个文件夹,里面的所有文件和子文件夹都会被复制。shutil.copytree 在复制文件时会使用 shutil.copy2

所以,你提到的 cp -r 的对应功能就是 shutil.copytree,因为 cp -r 是用来复制一个文件夹及其里面的文件和子文件夹,就像 shutil.copytree 一样。如果没有 -r,那么 cp 就只会像 shutil.copyshutil.copy2 一样,复制单个文件。

14

为了补充一下Tzotgns的回答,这里有一种替代的方法,可以递归地复制文件和文件夹。(适用于Python 3.X)

import os, shutil

root_src_dir = r'C:\MyMusic'    #Path/Location of the source directory
root_dst_dir = 'D:MusicBackUp'  #Path to the destination folder

for src_dir, dirs, files in os.walk(root_src_dir):
    dst_dir = src_dir.replace(root_src_dir, root_dst_dir, 1)
    if not os.path.exists(dst_dir):
        os.makedirs(dst_dir)
    for file_ in files:
        src_file = os.path.join(src_dir, file_)
        dst_file = os.path.join(dst_dir, file_)
        if os.path.exists(dst_file):
            os.remove(dst_file)
        shutil.copy(src_file, dst_dir)

如果这是你第一次接触,而且对如何递归复制文件和文件夹一无所知,希望这能对你有所帮助。

193

我建议你先使用 shutil.copytree 这个方法,如果出现了错误,那就再试试用 shutil.copy

import shutil, errno

def copyanything(src, dst):
    try:
        shutil.copytree(src, dst)
    except OSError as exc: # python >2.5
        if exc.errno in (errno.ENOTDIR, errno.EINVAL):
            shutil.copy(src, dst)
        else: raise

撰写回答