To copy a file in Python, use the shutil
module, which provides high-level file operations. Here are the common methods and best practices:
1. Basic File Copy
Use shutil.copy()
to copy a file to a destination directory or file path.
import shutil
# Copy a file to a directory (keeps original filename)
shutil.copy("source.txt", "destination_dir/")
# Copy and rename the file
shutil.copy("source.txt", "destination_dir/new_name.txt")
Notes:
- Preserves file permissions but not metadata (e.g., timestamps).
- Overwrites the destination file if it exists.
2. Preserve Metadata
Use shutil.copy2()
to retain file metadata (e.g., creation/modification times):
shutil.copy2("source.txt", "destination.txt")
3. Copy File Contents Only
Use shutil.copyfile()
to copy content without metadata or permissions:
shutil.copyfile("source.txt", "destination.txt")
4. Handle Directories
Use shutil.copytree()
to copy an entire directory tree:
shutil.copytree("source_dir", "destination_dir")
Error Handling
Wrap the operation in a try
block to catch common errors:
import shutil
import FileNotFoundError
try:
shutil.copy("source.txt", "destination.txt")
except FileNotFoundError:
print("Source file not found.")
except PermissionError:
print("Permission denied.")
except shutil.SameFileError:
print("Source and destination are the same file.")
Key Notes
- Overwrite Behavior: All
shutil
methods overwrite the destination file if it exists. - Cross-Platform: Works on Windows, macOS, and Linux.
- Symbolic Links: By default,
shutil.copy
follows symlinks. Usecopy2(src, dst, follow_symlinks=False)
to copy the symlink itself. - Large Files: Uses efficient buffering for large files.
Example Workflow
import os
import shutil
source = "data/report.pdf"
destination = "backups/report_backup.pdf"
# Ensure the destination directory exists
os.makedirs(os.path.dirname(destination), exist_ok=True)
# Copy the file
try:
shutil.copy2(source, destination)
print(f"Copied {source} to {destination}")
except FileNotFoundError:
print(f"Error: {source} not found.")
Alternatives
pathlib
(Python 3.5+):
from pathlib import Path
Path("source.txt").copy_to("destination.txt")
- Avoid
os.system
:
# ❌ Platform-dependent and insecure
os.system("cp source.txt destination.txt")
Use shutil.copy()
for most use cases and shutil.copy2()
to preserve metadata. Always handle exceptions for robustness!