Automation
shutil — High-level File Operations
Purpose: High-level file operations. The shutil module includes high-level file operations such as copying and archiving.
Copying Files
copyfile() copies the contents of the source to the destination and raises IOError if it does not have permission to write to the destination file.
#shutil_copyfile.py
import glob
import shutil
print('BEFORE:', glob.glob('shutil_copyfile.*'))
shutil.copyfile('shutil_copyfile.py', 'shutil_copyfile.py.copy')
print('AFTER:', glob.glob('shutil_copyfile.*'))
Because the function opens the input file for reading, regardless of its type, special files (such as Unix device nodes) cannot be copied as new special files with copyfile().
$ python3 shutil_copyfile.py
BEFORE: ['shutil_copyfile.py']
AFTER: ['shutil_copyfile.py', 'shutil_copyfile.py.copy']
The implementation of copyfile() uses the lower-level function copyfileobj(). While the arguments to copyfile() are filenames, the arguments to copyfileobj() are open file handles. The optional third argument is a buffer length to use for reading in blocks.
#shutil_copyfileobj.py
import io
import os
import shutil
import sys
class VerboseStringIO(io.StringIO):
def read(self, n=-1):
next = io.StringIO.read(self, n)
print('read({}) got {} bytes'.format(n, len(next)))
return next
lorem_ipsum = '''Lorem ipsum dolor sit amet, consectetuer
adipiscing elit. Vestibulum aliquam mollis dolor. Donec
vulputate nunc ut diam. Ut rutrum mi vel sem. Vestibulum
ante ipsum.'''
print('Default:')
input = VerboseStringIO(lorem_ipsum)
output = io.StringIO()
shutil.copyfileobj(input, output)
print()
print('All at once:')
input = VerboseStringIO(lorem_ipsum)
output = io.StringIO()
shutil.copyfileobj(input, output, -1)
print()
print('Blocks of 256:')
input = VerboseStringIO(lorem_ipsum)
output = io.StringIO()
shutil.copyfileobj(input, output, 256)
The default behavior is to read using large blocks. Use -1 to read all of the input at one time or another positive integer to set a specific block size. This example uses several different block sizes to show the effect.
$ python3 shutil_copyfileobj.py
Default:
read(16384) got 166 bytes
read(16384) got 0 bytes
All at once:
read(-1) got 166 bytes
read(-1) got 0 bytes
Blocks of 256:
read(256) got 166 bytes
read(256) got 0 bytes
Regular Expressions
Regular expressions are a powerful tool for various kinds of string manipulation. They are a domain specific language (DSL) that is present as a library in most modern programming languages, not just Python. They are useful for two main tasks:
- verifying that strings match a pattern (for instance, that a string has the format of an email address),
- performing substitutions in a string (such as changing all American spellings to British ones).
Regular expressions in Python can be accessed using the re module, which is part of the standard library. After you’ve defined a regular expression, the re.match function can be used to determine whether it matches at the beginning of a string.
If it does, match returns an object representing the match, if not, it returns None. To avoid any confusion while working with regular expressions, we would use raw strings as r”expression”. Raw strings don’t escape anything, which makes use of regular expressions easier.
Example:
import re
pattern = r"spam"
if re.match(pattern, "spamspamspam"):
print("Match")
else:
print("No match")
Result:
>>>
Match
>>>
Other functions to match patterns are re.search and re.findall. The function re.search finds a match of a pattern anywhere in the string. The function re.findall returns a list of all substrings that match a pattern.
Example:
import re
pattern = r"spam"
if re.match(pattern, "eggspamsausagespam"):
print("Match")
else:
print("No match")
if re.search(pattern, "eggspamsausagespam"):
print("Match")
else:
print("No match")
print(re.findall(pattern, "eggspamsausagespam"))
Result:
>>>
No match
Match
['spam', 'spam']
>>>