Rolex Pearlmaster Replica
  Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
This article is part of in the series
Published: Wednesday 10th April 2013
Last Updated: Wednesday 29th December 2021

Ever tried to copy a directory/folder in Python? Ever failed? No matter. Try again!

If you haven't already read it, look at the article How to Copy a File in Python with shutil for an explanation of how to copy files with shutil.

Recursively Copying a Directory/Folder of Files in Python

In the article that was mentioned above, we saw how to copy individual files in Python. I think you'll agree that much more useful is the ability to copy entire directories into other directories.

Python's shutil module once again saves our butts and has a function called copytree for doing just what we want.

We don't need that drastic of a change, so I'll modify our code above slightly to be able to copy directories as follows:

[python]
import shutil

def copyDirectory(src, dest):
try:
shutil.copytree(src, dest)
# Directories are the same
except shutil.Error as e:
print('Directory not copied. Error: %s' % e)
# Any error saying that the directory doesn't exist
except OSError as e:
print('Directory not copied. Error: %s' % e)
[/python]

Ok, nice! Almost the same as our function that copies single files, but it only allows to copy directories instead of files and the exceptions thrown are a bit different. Awesome.

Copying Both Files and Directories in Python

But what if we want one solid function that copies both files and directories? No problem! We can write a simple, slightly more complex function for that.

Observe:

[python]
import errno

def copy(src, dest):
try:
shutil.copytree(src, dest)
except OSError as e:
# If the error was caused because the source wasn't a directory
if e.errno == errno.ENOTDIR:
shutil.copy(src, dest)
else:
print('Directory not copied. Error: %s' % e)
[/python]

This function will copy both files and directories. First, we put our copytree function in a try block to catch any nasty exceptions. If our exception was caused because the source directory/folder was actually a file, then we copy the file instead. Simple stuff.

A note to add is that it really isn't possible to actually copy a directory over. You need to recursively walk the directories and create the directory structure based on the old one, and copy the files in each sub-directory to their proper directories at the destination. If you wished to implement this yourself, see this article for an example of how to recursively walk directories in Python.

Ignoring Files and Directories

The function shutil.copytree takes in an argument that allows you to specify a function that returns a list of directories or files that should be ignored.
A simple example function that does this is as follows:
[python]
def ignore_function(ignore):
def _ignore_(path, names):
ignored_names = []
if ignore in names:
ignored_names.append(ignore)
return set(ignored_names)
return _ignore_
[/python]

Alright, what does this function do? Well, we specify some sort of file or directory name as the argument ignore, which acts as the filter for names. If ignore is in names, then we add it to an ignored_names list that specifies to copytree which files or directories to skip.

How would we use this function? See our modified copy function below:

[python]
def copy(src, dest):
try:
shutil.copytree(src, dest, ignore=ignore_function('specificfile.file'))
except OSError as e:
# If the error was caused because the source wasn't a directory
if e.errno == errno.ENOTDIR:
shutil.copy(src, dest)
else:
print('Directory not copied. Error: %s' % e)
[/python]

But what if we want to filter out more than just one file? Luckily, shutil has got us covered again! It's got a function called shutil.ignore_patterns that allows us to specify glob patterns to filter out files and directories. See our once again modified copy function below:

[python]
def copy(src, dest):
try:
shutil.copytree(src, dest, ignore=ignore_patterns('*.py', '*.sh', 'specificfile.file'))
except OSError as e:
# If the error was caused because the source wasn't a directory
if e.errno == errno.ENOTDIR:
shutil.copy(src, dest)
else:
print('Directory not copied. Error: %s' % e)
[/python]

This will ignore all Python files, shell files and our own specific file when copying over the directory. ignore_patterns takes in arguments that specify the patterns to ignore and returns a function that copytree can understand, a lot like how our custom function ignore_function did it, but more robust.

That's all I have to share with you!

Peace.

About The Author

Joey Payne

Latest Articles


Tags

  • Unpickling
  • array
  • sorting
  • reversal
  • Python salaries
  • list sort
  • Pip
  • .groupby()
  • pyenv global
  • NumPy arrays
  • Modulo
  • OpenCV
  • Torrent
  • data
  • int function
  • file conversion
  • calculus
  • python typing
  • encryption
  • strings
  • big o calculator
  • gamin
  • HTML
  • list
  • insertion sort
  • in place reversal
  • learn python
  • String
  • python packages
  • FastAPI
  • argparse
  • zeros() function
  • AWS Lambda
  • Scikit Learn
  • Free
  • classes
  • turtle
  • convert file
  • abs()
  • python do while
  • set operations
  • data visualization
  • efficient coding
  • data analysis
  • HTML Parser
  • circular queue
  • effiiciency
  • Learning
  • windows
  • reverse
  • Python IDE
  • python maps
  • dataframes
  • Num Py Zeros
  • Python Lists
  • Fprintf
  • Version
  • immutable
  • python turtle
  • pandoc
  • semantic kernel
  • do while
  • set
  • tabulate
  • optimize code
  • object oriented
  • HTML Extraction
  • head
  • selection sort
  • Programming
  • install python on windows
  • reverse string
  • python Code Editors
  • Pytest
  • pandas.reset_index
  • NumPy
  • Infinite Numbers in Python
  • Python Readlines()
  • Trial
  • youtube
  • interactive
  • deep
  • kernel
  • while loop
  • union
  • tutorials
  • audio
  • github
  • Parsing
  • tail
  • merge sort
  • Programming language
  • remove python
  • concatenate string
  • Code Editors
  • unittest
  • reset_index()
  • Train Test Split
  • Local Testing Server
  • Python Input
  • Studio
  • excel
  • sgd
  • deeplearning
  • pandas
  • class python
  • intersection
  • logic
  • pydub
  • git
  • Scrapping
  • priority queue
  • quick sort
  • web development
  • uninstall python
  • python string
  • code interface
  • PyUnit
  • round numbers
  • train_test_split()
  • Flask module
  • Software
  • FL
  • llm
  • data science
  • testing
  • pathlib
  • oop
  • gui
  • visualization
  • audio edit
  • requests
  • stack
  • min heap
  • Linked List
  • machine learning
  • scripts
  • compare string
  • time delay
  • PythonZip
  • pandas dataframes
  • arange() method
  • SQLAlchemy
  • Activator
  • Music
  • AI
  • ML
  • import
  • file
  • jinja
  • pysimplegui
  • notebook
  • decouple
  • queue
  • heapify
  • Singly Linked List
  • intro
  • python scripts
  • learning python
  • python bugs
  • ZipFunction
  • plus equals
  • np.linspace
  • SQLAlchemy advance
  • Download
  • No
  • nlp
  • machiine learning
  • dask
  • file management
  • jinja2
  • ui
  • tdqm
  • configuration
  • deque
  • heap
  • Data Structure
  • howto
  • dict
  • csv in python
  • logging in python
  • Python Counter
  • python subprocess
  • numpy module
  • Python code generators
  • KMS
  • Office
  • modules
  • web scraping
  • scalable
  • pipx
  • templates
  • python not
  • pytesseract
  • env
  • push
  • search
  • Node
  • python tutorial
  • dictionary
  • csv file python
  • python logging
  • Counter class
  • Python assert
  • linspace
  • numbers_list
  • Tool
  • Key
  • automation
  • website data
  • autoscale
  • packages
  • snusbase
  • boolean
  • ocr
  • pyside6
  • pop
  • binary search
  • Insert Node
  • Python tips
  • python dictionary
  • Python's Built-in CSV Library
  • logging APIs
  • Constructing Counters
  • Assertions
  • Matplotlib Plotting
  • any() Function
  • Activation
  • Patch
  • threading
  • scrapy
  • game analysis
  • dependencies
  • security
  • not operation
  • pdf
  • build gui
  • dequeue
  • linear search
  • Add Node
  • Python tools
  • function
  • python update
  • logging module
  • Concatenate Data Frames
  • python comments
  • matplotlib
  • Recursion Limit
  • License
  • Pirated
  • square root
  • website extract python
  • steamspy
  • processing
  • cybersecurity
  • variable
  • image processing
  • incrementing
  • Data structures
  • algorithm
  • Print Node
  • installation
  • python function
  • pandas installation
  • Zen of Python
  • concatenation
  • Echo Client
  • Pygame
  • NumPy Pad()
  • Unlock
  • Bypass
  • pytorch
  • zipp
  • steam
  • multiprocessing
  • type hinting
  • global
  • argh
  • c vs python
  • Python
  • stacks
  • Sort
  • algorithms
  • install python
  • Scopes
  • how to install pandas
  • Philosophy of Programming
  • concat() function
  • Socket State
  • % Operator
  • Python YAML
  • Crack
  • Reddit
  • lightning
  • zip files
  • python reduce
  • library
  • dynamic
  • local
  • command line
  • define function
  • Pickle
  • enqueue
  • ascending
  • remove a node
  • Django
  • function scope
  • Tuple in Python
  • pandas groupby
  • pyenv
  • socket programming
  • Python Modulo
  • Dictionary Update()
  • Hack
  • sdk
  • python automation
  • main
  • reduce
  • typing
  • ord
  • print
  • network
  • matplotlib inline
  • Pickling
  • datastructure
  • bubble sort
  • find a node
  • Flask
  • calling function
  • tuple
  • GroupBy method
  • Pythonbrew
  • Np.Arange()
  • Modulo Operator
  • Python Or Operator
  • Keygen
  • cloud
  • pyautogui
  • python main
  • reduce function
  • type hints
  • python ord
  • format
  • python socket
  • jupyter
  • Python is a beautiful language.