Python Module 4
Python Module 4
Organizing files:
the shutil module
The shutil (or shell utilities) module has functions to let you copy, move, rename, and delete files in your Python
programs.
Copying Files and Folders
The shutil module provides functions for copying files, as well as entire folders.Calling shutil.copy(source,
destination) will copy the file at the path source to the folder at the path destination. (Both source and destination are
strings.) If destination is a filename, it will be used as the new name of the copied file. This function returns a string
of the path of the copied file.
>>> import shutil, os
>>> os.chdir('C:\\')
>>> shutil.copy('C:\\spam.txt', 'C:\\delicious')
'C:\\delicious\\spam.txt'
>>> shutil.copy('hello.txt', 'C:\\delicious\\hello2.txt')
'C:\\delicious\\hello2.txt'
Moving and Renaming Files and Folders
Calling shutil.move(source, destination) will move the file or folder at the path source to the path destination and
will return a string of the absolute path of the new location.
If destination points to a folder, the source file gets moved into destination and keeps its current filename.
>>> import shutil
>>> shutil.move('C:\\hello.txt', 'C:\\folder1')
'C:\\folder1\\hello.txt'
>>> shutil.move('C:\\hello.txt', 'C:\\folder1\\new_hello.txt')
'C:\\file1\\new_hello.txt'
Permanently Deleting Files and Folders
You can delete a single file or a single empty folder with functions in the os module, whereas to delete a folder
and all of its contents, you use the shutil module.
• Calling os.unlink(path) will delete the file at path.
• Calling os.rmdir(path) will delete the folder at path. This folder must be
empty of any files or folders.
• Calling shutil.rmtree(path) will remove the folder at path, and all files
and folders it contains will also be deleted.
Safe Deletes with the send2trash Module: Since Python’s built-in shutil.rmtree() function irreversibly deletes files
and folders, it can be dangerous to use. A much better way to delete files and folders is with the third-party send2trash
module. You can install this module by running pip install send2trash from a Terminal window. Using send2trash is
much safer than Python’s regular delete functions, because it will send folders and files to your computer’s trash or
recycle bin instead of permanently deleting them. If a bug in your program deletes something with send2trash you
didn’t intend to delete, you can later restore it from the recycle bin.
>>> import send2trash
>>> newFile = open('hello.txt', 'a') # creates the file
>>> newFile.write('apple is not a vegetable.')
25
>>> newFile.close()
>>> send2trash.send2trash('hello.txt')
walking a directory tree: Say you want to list every file in some folder and also every file in every subfolder of that
folder. That is, you want to walk through the directory tree, touching each file as you go.
import os
for folderName, subfolders, filenames in os.walk('C:\\program'):
print('The current folder is ' + folderName)
for subfolder in subfolders:
print('SUBFOLDER OF ' + folderName + ': ' + subfolder)
for filename in filenames:
print('FILE INSIDE ' + folderName + ': '+ filename)
print('')
The os.walk() function is passed a single string value: the path of a folder. You can use os.walk() in a for loop
statement to walk a directory tree, much like how you can use the range() function to walk over a range of numbers.
Unlike range(), the os.walk() function will return three values on each iteration through the loop:
1. A string of the current folder’s name
2. A list of strings of the folders in the current folder
3. A list of strings of the files in the current folder
compressing files with the zipfile module:You may be familiar with ZIP files (with the .zip file extension), which
can hold the compressed contents of many other files. Compressing a file reduces its size, which is useful when
transferring it over the Internet. And since a ZIP file can also contain multiple files and subfolders, it’s a handy way
to package several files into one. This single file, called an archive file, can then be, say, attached to an email.
Your Python programs can both create and open (or extract) ZIP files using functions in the zipfile module.
Reading ZIP Files: To read the contents of a ZIP file, first you must create a ZipFile object (note the capital letters Z
and F). To create a ZipFile object, call the zipfile.ZipFile() function, passing it a string of the .zip file’s filename.
Note that zipfile is the name of the Python module, and ZipFile() is the name of the function.
>>> import zipfile, os
>>> os.chdir('C:\\') # move to the folder with example.zip
>>> exampleZip = zipfile.ZipFile('example.zip')
>>> exampleZip.namelist()
['spam.txt', 'cats/', 'cats/catnames.txt', 'cats/zophie.jpg']
>>> spamInfo = exampleZip.getinfo('spam.txt')
>>> spamInfo.file_size
13908
>>> spamInfo.compress_size
3828
>>> 'Compressed file is %sx smaller!' % (round(spamInfo.file_size / spamInfo.compress_size, 2))
'Compressed file is 3.63x smaller!'
>>> exampleZip.close()
Extracting from ZIP Files
The extractall() method for ZipFile objects extracts all the files and folders from a ZIP file into the current working
directory.
>>> import zipfile, os
>>> os.chdir('C:\\') # move to the folder with example.zip
>>> exampleZip = zipfile.ZipFile('example.zip')
>>> exampleZip.extractall()
>>> exampleZip.close()
Creating and Adding to ZIP Files
To create your own compressed ZIP files, you must open the ZipFile object in write mode by passing 'w' as the
second argument. When you pass a path to the write() method of a ZipFile object, Python will compress the file at
that path and add it into the ZIP file. The write() method’s first argument is a string of the filename to add. The second
argument is the compression type parameter, which tells the computer what algorithm it should use to compress the
files; you can always just set this value to zipfile.ZIP_DEFLATED.
>>> import zipfile
>>> newZip = zipfile.ZipFile('new.zip', 'w')
>>> newZip.write('spam.txt', compress_type=zipfile.ZIP_DEFLATED)
>>> newZip.close()
Project: renaming files with American-Style dates to european-Style dates
Say your boss emails you thousands of files with American-style dates (MM-DD-YYYY) in their names and needs
them renamed to Europeanstyle dates (DD-MM-YYYY).
Here’s what the program does:
• It searches all the filenames in the current working directory for
American-style dates.
• When one is found, it renames the file with the month and day swapped
to make it European-style.
This means the code will need to do the following:
• Create a regex that can identify the text pattern of American-style dates.
• Call os.listdir() to find all the files in the working directory.
• Loop over each filename, using the regex to check whether it has a date.
• If it has a date, rename the file with shutil.move().
Project: Backing up a folder into a ziP file
Say you’re working on a project whose files you keep in a folder named C:\AlsPythonBook. You’re worried about
losing your work, so you’d like to create ZIP file “snapshots” of the entire folder. You’d like to keep different
versions, so you want the ZIP file’s filename to increment each time it is made; for example, AlsPythonBook_1.zip,
AlsPythonBook_2.zip, AlsPythonBook_3.zip, and so on.
raising exceptions: Python raises an exception whenever it tries to execute invalid code. Exceptions are raised with
a raise statement. In code, a raise statement
consists of the following:
• The raise keyword
• A call to the Exception() function
• A string with a helpful error message passed to the Exception() function
>>> raise Exception('This is the error message.')
Traceback (most recent call last):
File "<pyshell#191>", line 1, in <module>
raise Exception('This is the error message.')
Exception: This is the error message.
getting the traceback as a String
When Python encounters an error, it produces a treasure trove of error information called the traceback. The
traceback includes the error message, the line number of the line that caused the error, and the sequence of the
function calls that led to the error. This sequence of calls is called the call stack.
def spam():
func()
def func():
raise Exception('This is the error message.')
spam()
When you run errorExample.py, the output will look like this:
Traceback (most recent call last):
File "errorExample.py", line 7, in <module>
spam()
File "errorExample.py", line 2, in spam
func()
File "errorExample.py", line 5, in func
raise Exception('This is the error message.')
Exception: This is the error message.
Assertions
An assertion is a sanity check to make sure your code isn’t doing something obviously wrong. These sanity checks
are performed by assert statements. If the sanity check fails, then an AssertionError exception is raised. In code, an
assert statement consists of the following:
• The assert keyword
• A condition (that is, an expression that evaluates to True or False)
• A comma
• A string to display when the condition is False
def set_age(age):
assert age >= 0, "Age cannot be negative."
print(f"Age is set to {age}.")
set_age(-5)
logging
If you’ve ever put a print() statement in your code to output some variable’s value while your program is running,
you’ve used a form of logging to debug your code. Logging is a great way to understand what’s happening in your
program and in what order its happening. Python’s logging module makes it easy to create a record of custom
messages that you write. These log messages will describe when the program execution has reached the logging
function call and list any variables you have specified at that point in time. On the other hand, a missing log message
indicates a part of the code was skipped and never executed.
import logging
logging.basicConfig(level=logging.DEBUG, format=' %(asctime)s - %(levelname)s - %(message)s')
import logging
logging.basicConfig(level=logging.DEBUG, format=' %(asctime)s - %(levelname)s - %(message)s')
logging.debug('Start of program')
def factorial(n):
logging.debug('Start of factorial(%s%%)' % (n))
total = 1
for i in range(n + 1):
total *= i
logging.debug('i is ' + str(i) + ', total is ' + str(total))
logging.debug('End of factorial(%s%%)' % (n))
return total
print(factorial(5))
logging.debug('End of program')
2015-05-23 16:20:12,664 - DEBUG - Start of program
2015-05-23 16:20:12,664 - DEBUG - Start of factorial(5)
2015-05-23 16:20:12,665 - DEBUG - i is 0, total is 0
2015-05-23 16:20:12,668 - DEBUG - i is 1, total is 0
2015-05-23 16:20:12,670 - DEBUG - i is 2, total is 0
2015-05-23 16:20:12,673 - DEBUG - i is 3, total is 0
2015-05-23 16:20:12,675 - DEBUG - i is 4, total is 0
2015-05-23 16:20:12,678 - DEBUG - i is 5, total is 0
2015-05-23 16:20:12,680 - DEBUG - End of factorial(5)
120
2015-05-23 16:20:12,684 - DEBUG - End of program
Disabling Logging
After you’ve debugged your program, you probably don’t want all these log messages cluttering the screen. The
logging.disable() function disables these so that you don’t have to go into your program and remove all the logging
calls by hand. You simply pass logging.disable() a logging level, and it will suppress all log messages at that level or
lower. So if you want to disable logging entirely, just add logging.disable(logging.CRITICAL) to your program.
>>> import logging
>>> logging.basicConfig(level=logging.INFO, format=' %(asctime)s - %(levelname)s - %(message)s')
>>> logging.critical('Critical error! Critical error!')
2015-05-22 11:10:48,054 - CRITICAL - Critical error! Critical error!
>>> logging.disable(logging.CRITICAL)
>>> logging.critical('Critical error! Critical error!')
>>> logging.error('Error! Error!')
Logging to a File
Instead of displaying the log messages to the screen, you can write them to a text file. The logging.basicConfig()
function takes a filename keyword argument.
import logging
logging.basicConfig(filename='myProgramLog.txt', level=logging.DEBUG, format=' %(asctime)s - %(levelname)s -
%(message)s')
IDLE’s Debugger
The debugger is a feature of IDLE that allows you to execute your program one line at a time. The debugger will run
a single line of code and then wait for you to tell it to continue. By running your program “under the debugger” like
this, you can take as much time as you want to examine the values in the variables at any given point during the
program’s lifetime. This is a valuable tool for tracking down bugs.
While the Debug Control window is displayed, any time you run a program from the file editor, the debugger will
pause execution before the first instruction and display the following:
• The line of code that is about to be executed
• A list of all local variables and their values
• A list of all global variables and their values
The program will stay paused until you press one of the five buttons in the Debug Control window: Go, Step, Over,
Out, or Quit.
Go:Clicking the Go button will cause the program to execute normally until it terminates or reaches a breakpoint. If
you are done debugging and want the program to continue normally, click the Go button.
Step:Clicking the Step button will cause the debugger to execute the next line of code and then pause again. The
Debug Control window’s list of global and local variables will be updated if their values change. If the next line of
code is a function call, the debugger will “step into” that function and jump to the first line of code of that function.
Over: Clicking the Over button will execute the next line of code, similar to the Step button. However, if the next line
of code is a function call, the Over button will “step over” the code in the function. The function’s code will be
executed at full speed, and the debugger will pause as soon as the function call returns. For example, if the next line
of code is a print() call, you don’t really care about code inside the built-in print() function; you just want the string
you pass it printed to the screen. For this reason, using the Over button is more common than the Step button.
Out: Clicking the Out button will cause the debugger to execute lines of code at full speed until it returns from the
current function. If you have stepped into a function call with the Step button and now simply want to keep executing
instructions until you get back out, click the Out button to “step out” of the current function call.
Quit: If you want to stop debugging entirely and not bother to continue executing the rest of the program, click the
Quit button. The Quit button will immediately terminate the program. If you want to run your program normally
again, select Debug4Debugger again to disable the debugger.
Debugging a Number Adding Program
Output:
Halfway done!
Heads came up 490 times.
Thank You