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 shutilmethods overwrite the destination file if it exists.
- Cross-Platform: Works on Windows, macOS, and Linux.
- Symbolic Links: By default, shutil.copyfollows 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!