Python language basics 84: starting with file I/O
March 5, 2016 Leave a comment
In the previous post we finished discussing the basics of object inheritance in Python. We saw an example where the Dog and a Duck classes inherited from an abstract base class called Animal. All common functionality was encapsulated within the Animal class. Dog and Duck retained the code specific to them.
In this post we’ll start looking into something very different: file input and output.
File related actions
The function to open a file is aptly called “open”. We can pass the following arguments to it:
- The file path
- The file open mode – see below for more details
- The encoding, most often UTF-8 which is by far the most widely used character encoding type on the Internet
The file path is probably clear. It can be something like “source.txt”. An often recurring annoyance is the file path delimiter in various operating systems: do we use ‘/’, or ‘\’ or even ‘\\’ in the file paths? It’s best to start with a built-in function of Python already now that can combine the various sections into OS-specific file paths: os.path.join. We’ll see it in action in a bit.
What’s file open mode about? We can also call it file access mode. There are various things you can perform on a file once it is open: read, write, append something to it and some more. These modes are denoted by the following string characters:
- r: ‘read’, this is the default access mode if the parameter is omitted
- w: ‘write’, remove the existing content of the file and write new content to it
- a: ‘append’, append to the file, do not remove what’s in it
- b: ‘binary’, open for binary reading
- t: ‘text’, open as text
- x: ‘exclusive creation’, create the file, throw exception if the file already exists
These codes can be combined. E.g. ‘rw’ means open the file for reading and writing. You’ll find more access mode examples on this Python tutorial page.
First example: writing to a file
Let’s see the first example. We’ll go through the file I/O related techniques step by step. We’ll start with some code that we’ll improve later on, but it’s important to get the basics right.
The open method returns a file handle that has a write method. The file handle must be closed with the close method after all the writes are done otherwise the file handle remains open. The content will only be written to the file once the file handle is closed.
Here’s an example:
import os.path fullpath = os.path.join('C:/', 'tmp', 'source.txt') file = open(fullpath, mode='wt', encoding='UTF-8') file.write('This is some content, ') file.write('this is some more content, ') file.write('good bye for now.') file.close()
fullpath will be joined to c:\tmp\source.txt on Windows. We then open the file for writing in text mode and write some strings to it. We finally close the file.
Note that I actually have a tmp folder on my C: drive. There was no source.txt file before running the code so it was created for me. However, if I had no tmp folder then the code would fail:
FileNotFoundError: [Errno 2] No such file or directory: ‘C:/nosuchfolder\\source.txt’
The above code is not very robust to say the least. There are several things that can go wrong during file operations:
- The path doesn’t exist
- The path exists but the thread that the code is running under has no access to it, e.g. it’s not allowed to create a new file in that folder
- Something goes wrong when writing to the file, an exception is thrown and the file.close method is never reached. This results in a potential memory leak as the file handle hasn’t been closed
We’ll look into ways to improve the above code in the next post before we consider other file related operations.
Read all Python-related posts on this blog here.