Various methods to copy, delete and create files and folders. Inludes methods to move files and folders to the trash bin instead of deleting them.
The following imports will be needed:
import os
import shutil
from send2trash import send2trash
Creating directories
This method creates directories like mkdirs
does, but without worrying
if the directory structure already exists. Plus, it supports
passing a complete filename instead of only its path, if include=False
is used.
Note: this method is also used in several snippets below.
def make_dirs(filename, inclusive=False):
'''
Creates intermediate directories for the given file (not dir!)
'''
f = filename if inclusive else os.path.dirname(filename)
if not os.path.exists(f):
try:
os.makedirs(f)
except OSError as exc:
if exc.errno != errno.EEXIST:
raise
Deleting directories
The send2trash
package can delete non-empty folder structures, shutil
cannot.
def rm_dir(path, trash=False):
'''
Removes a non-empty directory or file to the trash
'''
if os.path.isdir(path):
if trash:
send2trash(path)
else:
shutil.rmtree(path)
Copying directories
shutil.copytree
is usually a good fit for copying directory structures,
except when the target directory is not empty. It is designed
to copy into empty directories only.
The snippet below, found here replaces copytree
with a
version that can copy and recursively merge directories into existing ones.
def copytree(src, dst, symlinks=False, ignore=None):
'''
A fixed version of shutil.copytree. It's basically copied 1-1, except the first
os.makedirs() put behind an if-else-construct.
Credits to https://stackoverflow.com/a/12687372/609794
'''
names = os.listdir(src)
if ignore is not None:
ignored_names = ignore(src, names)
else:
ignored_names = set()
if not os.path.isdir(dst): # This one line does the trick
os.makedirs(dst)
errors = []
for name in names:
if name in ignored_names:
continue
srcname = os.path.join(src, name)
dstname = os.path.join(dst, name)
try:
if symlinks and os.path.islink(srcname):
linkto = os.readlink(srcname)
os.symlink(linkto, dstname)
elif os.path.isdir(srcname):
copytree(srcname, dstname, symlinks, ignore)
else:
# Will raise a SpecialFileError for unsupported file types
shutil.copy2(srcname, dstname)
# catch the Error from the recursive copytree so that we can
# continue with other files
except err:
errors.extend(err.args[0])
except EnvironmentError as why:
errors.append((srcname, dstname, str(why)))
try:
shutil.copystat(src, dst)
except OSError as why:
if WindowsError is not None and isinstance(why, WindowsError):
# Copying file access times may fail on Windows
pass
else:
errors.extend((src, dst, str(why)))
if errors:
raise errors
Move and copy files
To move or copy a file to a directory that might not exist yet, use these:
def copy_file(src, dst):
make_dirs(dst)
shutil.copy2(src, dst)
def move_file(src, dst):
make_dirs(dst)
shutil.move(src, dst)