Copying files or directories is essential when creating data backups or replicating template folders for new projects.
The Python standard library shutil module (Shell Utilities) allows executing these operations with simple function calls.
This article explains how to use shutil.copy() for single files and shutil.copytree() for entire directory trees.
1. Copying a File: shutil.copy()
The shutil.copy() function copies a specified file to another location.
Syntax:
import shutil
shutil.copy(src, dst)
- src (Source): The path of the file to copy.
- dst (Destination): The destination file path or directory path.
Specific Usage Example:
Here is an example of creating a backup for a presentation file.
import shutil
import os
# Source file
source_file = "presentation_v1.pptx"
# Destination directory (must be created beforehand)
backup_dir = "backup_storage"
if not os.path.exists(backup_dir):
os.makedirs(backup_dir)
print(f"Source: {source_file}")
# 1. Copy with specific filename (rename and copy)
# Saved as "backup_storage/presentation_v1_bk.pptx"
new_path = shutil.copy(source_file, os.path.join(backup_dir, "presentation_v1_bk.pptx"))
print(f"Backup created: {new_path}")
# 2. Copy to directory
# Saved as "backup_storage/presentation_v1.pptx" (same name)
dest_path = shutil.copy(source_file, backup_dir)
print(f"Copy to directory complete: {dest_path}")
Execution Result:
Source: presentation_v1.pptx
Backup created: backup_storage/presentation_v1_bk.pptx
Copy to directory complete: backup_storage/presentation_v1.pptx
Note on copy2():
The shutil module also provides copy2(), which is very similar to copy(). While copy() copies only file content and permissions, copy2() also preserves metadata (such as creation and modification times) as much as possible. Using copy2() is recommended when a complete backup is required.
2. Copying an Entire Directory: shutil.copytree()
To copy an entire directory, including all subdirectories and files while maintaining the structure, use shutil.copytree().
Syntax:
import shutil
shutil.copytree(src_dir, dst_dir)
Important Note: In principle, the destination directory must not exist. copytree() creates the destination directory during execution. If it already exists, a FileExistsError will occur (Python 3.8 and later allow overwriting with the dirs_exist_ok=True option).
Specific Usage Example:
Here is an example of replicating a development assets folder (images, CSS, etc.) as a release folder.
import shutil
import os
# Development directory (Source)
dev_assets = "project/dev/assets"
# Release directory (Destination)
# This directory must not exist yet
release_dir = "project/release/v1.0/assets"
print("Starting asset replication...")
try:
# Copy entire directory tree
shutil.copytree(dev_assets, release_dir)
print(f"Success: Copied '{dev_assets}' to '{release_dir}'.")
except FileExistsError:
print(f"Error: Destination '{release_dir}' already exists.")
except FileNotFoundError:
print(f"Error: Source '{dev_assets}' not found.")
Execution Result:
Starting asset replication...
Success: Copied 'project/dev/assets' to 'project/release/v1.0/assets'.
This recursively copies all files and subfolders within dev/assets into release/v1.0/assets.
Summary
- shutil.copy(src, dst): Copies a file. If
dstis a directory, the file is saved inside it with the same name. - shutil.copy2(src, dst): Copies file content along with metadata such as timestamps.
- shutil.copytree(src, dst): Recursively copies an entire directory. Generally,
dstmust be a directory that is created anew.
shutil is a powerful tool for scripts that automate file organization and backup processes.
