簡體   English   中英

如何在python中遞歸復制目錄並覆蓋所有?

[英]How to copy directory recursively in python and overwrite all?

我正在嘗試將/home/myUser/dir1/及其所有內容(及其內容等)復制到 python 中的/home/myuser/dir2/ 此外,我希望副本覆蓋dir2/中的所有內容。

看起來distutils.dir_util.copy_tree可能是完成這項工作的正確工具,但不確定是否有更容易/更明顯的東西可以用於這樣一個簡單的任務。

如果它是正確的工具,我該如何使用它? 根據文檔,它需要 8 個參數。 我是否必須通過所有 8 個,只是srcdstupdate ,如果是,如何(我是 Python 的新手)。

如果有更好的東西,有人可以給我一個例子並指出正確的方向嗎?

您可以使用distutils.dir_util.copy_tree 它工作得很好,您不必傳遞每個參數,只有srcdst是強制性的。

但是,在您的情況下,您不能使用類似shutil.copytree類的工具,因為它的行為不同:因為目標目錄必須不存在,因此該函數不能用於覆蓋其內容。

如果您想按照問題注釋中的建議使用cp工具,請注意使用subprocess模塊是當前推薦的生成新進程的方法,如您在 os.system 函數文檔中所見

看看shutil包,尤其是rmtreecopytree 您可以使用os.paths.exists(<path>)檢查文件/路徑是否存在。

import shutil
import os

def copy_and_overwrite(from_path, to_path):
    if os.path.exists(to_path):
        shutil.rmtree(to_path)
    shutil.copytree(from_path, to_path)

如果目錄已經存在,文森特關於copytree是正確的。 所以distutils是更好的版本。 以下是shutil.copytree的固定版本。 它基本上是 1-1 復制的,除了第一個os.makedirs()放在 if-else-construct 后面:

import os
from shutil import *
def copytree(src, dst, symlinks=False, ignore=None):
    names = os.listdir(src)
    if ignore is not None:
        ignored_names = ignore(src, names)
    else:
        ignored_names = set()

    if not os.path.isdir(dst): # This one line does the trick
        os.makedirs(dst)
    errors = []
    for name in names:
        if name in ignored_names:
            continue
        srcname = os.path.join(src, name)
        dstname = os.path.join(dst, name)
        try:
            if symlinks and os.path.islink(srcname):
                linkto = os.readlink(srcname)
                os.symlink(linkto, dstname)
            elif os.path.isdir(srcname):
                copytree(srcname, dstname, symlinks, ignore)
            else:
                # Will raise a SpecialFileError for unsupported file types
                copy2(srcname, dstname)
        # catch the Error from the recursive copytree so that we can
        # continue with other files
        except Error, err:
            errors.extend(err.args[0])
        except EnvironmentError, why:
            errors.append((srcname, dstname, str(why)))
    try:
        copystat(src, dst)
    except OSError, why:
        if WindowsError is not None and isinstance(why, WindowsError):
            # Copying file access times may fail on Windows
            pass
        else:
            errors.extend((src, dst, str(why)))
    if errors:
        raise Error, errors

這是一個簡單的解決方案,可以使用源遞歸覆蓋目標,並在執行過程中創建任何必要的目錄。 這不處理符號鏈接,但它是一個簡單的擴展(參見上面@Michael 的回答)。

def recursive_overwrite(src, dest, ignore=None):
    if os.path.isdir(src):
        if not os.path.isdir(dest):
            os.makedirs(dest)
        files = os.listdir(src)
        if ignore is not None:
            ignored = ignore(src, files)
        else:
            ignored = set()
        for f in files:
            if f not in ignored:
                recursive_overwrite(os.path.join(src, f), 
                                    os.path.join(dest, f), 
                                    ignore)
    else:
        shutil.copyfile(src, dest)

在 Python 3.8 中, dirs_exist_ok關鍵字參數被添加shutil.copytree()

dirs_exist_ok指示是否在dst或任何丟失的父目錄已經存在的情況下引發異常。

因此,即使目標目錄已經存在,以下內容也適用於最新版本的 Python:

shutil.copytree(src, dest, dirs_exist_ok=True)  # 3.8+ only!

一個主要的好處是它比distutils.dir_util.copy_tree()更靈活,因為它需要忽略文件的其他參數等(請參閱文檔)。 最重要的是,已接受的PEP 632還指出distutils將被棄用,隨后在 Python 3 的未來版本中將被刪除。

我的簡單回答。

def get_files_tree(src="src_path"):
    req_files = []
    for r, d, files in os.walk(src):
        for file in files:
            src_file = os.path.join(r, file)
            src_file = src_file.replace('\\', '/')
            if src_file.endswith('.db'):
                continue
            req_files.append(src_file)

    return req_files
def copy_tree_force(src_path="",dest_path=""):
    """
    make sure that all the paths has correct slash characters.
    """
    for cf in get_files_tree(src=src_path):
        df= cf.replace(src_path, dest_path)
        if not os.path.exists(os.path.dirname(df)):
            os.makedirs(os.path.dirname(df))
        shutil.copy2(cf, df)

shutil.copytree() 已更新。 您可以添加以下參數:

shutil.copytree(src, dst, dirs_exist_ok=True)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM