杰瑞科技汇

python copy folder

Of course! Copying a folder in Python is a common task. The best method depends on whether you need to preserve metadata (like permissions and timestamps) or just the file contents.

python copy folder-图1
(图片来源网络,侵删)

Here’s a breakdown of the best ways to do it, from the most recommended to more specialized cases.

The Recommended Method: shutil.copytree()

This is the standard, easiest, and most Pythonic way to copy an entire folder and all its contents. It's part of Python's built-in shutil module.

Key Features:

  • Copies the entire directory tree (subdirectories and files).
  • Preserves file permissions and metadata by default.
  • Handles symlinks correctly.

How to Use It

import shutil
import os
# Define the source and destination paths
source_folder = '/path/to/your/source_folder'
destination_folder = '/path/to/your/destination_folder'
# Make sure the destination parent directory exists
os.makedirs(destination_folder, exist_ok=True)
try:
    # The copytree function will copy the folder and all its contents
    shutil.copytree(source_folder, destination_folder)
    print(f"Folder copied successfully from {source_folder} to {destination_folder}")
except Exception as e:
    print(f"An error occurred: {e}")

Important Parameters for shutil.copytree()

  • dirs_exist_ok (Python 3.8+): This is a very useful parameter.

    python copy folder-图2
    (图片来源网络,侵删)
    • If dirs_exist_ok=False (the default), the function will raise a FileExistsError if the destination folder already exists.
    • If dirs_exist_ok=True, the function will copy the contents of the source folder into the existing destination folder, effectively merging them.

    Example of merging into an existing folder:

    # If destination_folder already exists, this will add source_folder's contents to it.
    shutil.copytree(source_folder, destination_folder, dirs_exist_ok=True)
  • ignore: You can provide a function to ignore certain files or directories. This is great for excluding temporary files, cache, or .git directories.

    Example of ignoring files:

    def ignore_files(directory, files):
        # This function will ignore any file or directory named 'temp' or '.DS_Store'
        return [f for f in files if f == 'temp' or f == '.DS_Store']
    shutil.copytree(source_folder, destination_folder, ignore=ignore_files)

Alternative: os.walk() with shutil.copy2()

If shutil.copytree() doesn't give you enough control, you can manually iterate through the folder using os.walk() and copy each file individually. This method is more verbose but gives you full control over the process.

python copy folder-图3
(图片来源网络,侵删)

Key Features:

  • Total flexibility to handle each file or directory as you wish.
  • You can add custom logic, logging, or error handling for each item.

How to Use It

import os
import shutil
source_folder = '/path/to/your/source_folder'
destination_folder = '/path/to/your/destination_folder'
# Create the destination directory if it doesn't exist
os.makedirs(destination_folder, exist_ok=True)
# Walk through the source directory
for root, dirs, files in os.walk(source_folder):
    # Calculate the destination path for the current subdirectory
    # e.g., /path/to/source_folder/subdir -> /path/to/destination_folder/subdir
    relative_path = os.path.relpath(root, source_folder)
    destination_path = os.path.join(destination_folder, relative_path)
    # Create the subdirectory in the destination if it doesn't exist
    if not os.path.exists(destination_path):
        os.makedirs(destination_path)
    # Copy each file in the current directory
    for file_name in files:
        source_file = os.path.join(root, file_name)
        destination_file = os.path.join(destination_path, file_name)
        print(f"Copying {source_file} to {destination_file}")
        shutil.copy2(source_file, destination_file) # copy2 preserves metadata
print("Folder copy complete.")

Why shutil.copy2()?

  • shutil.copy2() is used instead of shutil.copy() because it not only copies the file's content but also tries to preserve the original file's metadata (like modification time and permissions), similar to cp -p in Unix.

For Large Files: shutil.copytree() with copy_function

If you are dealing with very large files and want to show a progress bar, you can provide a custom copy function to shutil.copytree(). This is an advanced technique.

import shutil
import os
def copy_with_progress(src, dst):
    """A custom copy function that could be extended with a progress bar."""
    print(f"Copying large file from {src} to {dst}")
    return shutil.copy2(src, dst)
source_folder = '/path/to/large/source_folder'
destination_folder = '/path/to/large/destination_folder'
shutil.copytree(source_folder, destination_folder, copy_function=copy_with_progress)

Summary: Which Method Should You Use?

Method Best For Pros Cons
shutil.copytree() Most use cases. The go-to solution. Simple, one-line, preserves metadata, handles symlinks. Less flexible if you need to handle each file individually.
os.walk() + shutil.copy2() When you need fine-grained control. Full control over the process, easy to add custom logic or error handling per file. More verbose (more code), slightly slower due to manual iteration.
distutils.dir_util Legacy code (pre-Python 3.8). Very fast for copying large directory trees. Does not preserve metadata. Not recommended for new code.

Final Recommendation:

Start with shutil.copytree(). It's the standard, safest, and most efficient way to copy a folder in Python. Use its dirs_exist_ok and ignore parameters to handle common requirements. If you find yourself needing to do something special for every single file, then switch to the os.walk() method.

分享:
扫描分享到社交APP
上一篇
下一篇