Learn Python (Part 4)
While there are other programming languages that excel at file parsing (such as Perl), sometimes it will be more convenient to perform file manipulation in Python.In this section, we will go over the basics of reading from and writing to files using Python. We have read from files before, when we created password.py using the file open command and specified the file as read-only. There are a few more modes we need to know about. In addition to the r or read mode, there is w mode for write, and a mode for append. Two important modifiers for these are + and b. The + indicates that, in addition to the mode you chose, the file will also be writable. This is typically used as r+ for a file that you want to keep intact, but modify. The w mode overwrites the filename with a blank file when it opens it. The b flag isn’t used in UNIX, but in Windows mode it indicates that the file should be a binary file. To read and write a binary file in Windows you would use r+b. Once the file is open, the read and write functions come into play. There are three primary read methods. The read method reads from the file. If no argument is passed to read, it will read the whole file and return that information as a string. If your file is massive, this may be a problem. So, you can specify a number of bytes to read, and read will return only that number of bytes or an empty string if you are at the end of the file. The readline method returns an entire line as a string, and the readlines function returns the entire file as a list of strings.
You have a few options for reading files, but you have only one option for writing to files: the write method. The write method takes one argument: a string. It writes that string to the file at your current position. The write method returns None. So, the only way we will know that it didn’t write the full string is if it throws an exception.
The final two methods that we may use are seek and tell. These come into play particularly when you are dealing with binary files. The tell method tells you what your position is in the file, and the seek function allows you to move forward or backward in a file based on your position. The seek method takes two options: the offset you would like to advance, and the relative position. A value of 0 as the position means “from the start of the file”; 1 means “from the current position,” and 2 means “from the end of the file.” Here is an example of these methods. Modify this code to test all the differences.
# Open the file for writing
f = open(“test.txt”,”w”)
# Open the file for appending
f = open(“test.txt”,”a”)
f.write(“This is the endn”)
# Open the file for reading and modification
f = open(“test.txt”,”r+”)
# Print file contents
print “Current contents are:n” + f.read()
# Go to the end of the file and append
print “Starting file length is %d” % f.tell()
f.write(“This is the new end!n”)
print “End file length is %d” % f.tell()
# Go back to the beginning of the file for reading
print “nNew contents are:n” + f.read()
Sometimes bad things happen to good scripts. Exception handling allows us to handle those problems and either recover or present nicer error messages than the stack traces that are shown when something breaks and we don’t expect it. The two core elements of exception handling are the try and except keywords. The try block of code is what we are going to try to execute. If an error occurs in our try block, we have an except statement to handle it. Two other elements that may appear in exception handling blocks are else and finally. The else keyword is used for code that should run if no exception is raised, and the finally keyword is used for code that should be run regardless of errors.
Let’s look at a practical example. When we open files, sometimes the file may not exist. We can combat this in a number of ways, but since this is the exception handling section, we should probably try that one.
f = open(“/tmp/nessus.nbe”)
print “Error occurred opening file”
print “Unknown error occurred”
print “File contents successfully read”
print “Thanks for playing!”
This sample piece of code has all our conditions. In our try block, we try to open a file and print the contents. If the file fails to open, the code will raise an IOError exception, which we catch with except. If a different type of error from what we were expecting occurs, the second except statement will catch it and print a different error message. If there are no errors, a success message is printed. Regardless of what else happens in the try block, the finally statement will execute.
Try creating the file and then removing the file, and look at the differences:
# Test our exception handling code
$ touch /tmp/nessus.nbe
$ python exception.py
File contents successfully read
Thanks for playing!
# Without the file we should get an exception
$ rm /tmp/nessus.nbe
$ python exception.py
Error occurred opening file
Thanks for playing!
# With no exception handling
$ python withoutexception.py
Traceback (most recent call last):
File “a.py”, line 3, in <module>
f ” open(“/tmp/nessus.nbe”)
IOError: [Errno 2] No such file or directory: ‘/tmp/nessus.nbe’