The manipulation of files is an operation which sooner or later we’ll need to perform in our programs. The python built-in
open function returns a
file object, which lets us interact with files in different modes: we will see them in this article.
In this python tutorial you will learn:
- How to use the python open function.
- What are the various modes of operation which can be used with the python open function.
- How to interact with a file object.
- Why is important to close a file object, and how to do it.
Software Requirements and Conventions Used
|Category||Requirements, Conventions or Software Version Used|
|Other||No special permissions required.|
|Conventions||# – requires given linux commands to be executed with root privileges either directly as a root user or by use of
$ – requires given linux commands to be executed as a regular non-privileged user
>>> – python commands to be executed in an interactive shell
Python input and output statements
There are many reasons a program could need to interact with files: reading configurations and settings which will influence the behavior of the program itself, or perhaps persisting data. In this tutorial we will see how to accomplish such tasks, using the python open function and interacting with
The python open function
Before starting to read or write files, we need to learn how we can access them. The python open function opens a file and returns a
file object, raising an
OSError exception if the resource cannot be accessed. The function has only one mandatory argument,
file, which is the string or byte-object representing the path of the file to be opened:
>>> fobject = open('linuxconfig.txt')
Read mode – ‘r’
We opened the
linuxconfig.txt file, and the resulting file-object is now referenced by
fobject. It is a python
file-object which implements methods like
read. What if the
linuxconfig.txt file didn’t exist? A
FileNotFoundError exception would be raised:
>>> fobject = open('linuxconfig.txt') Traceback (most recent call last): File "<stdin>", line 1, in <module> FileNotFoundError: [Errno 2] No such file or directory: 'linuxconfig.txt'
As we just said above, the only mandatory argument of the python open function is
file. When used as in the example above, the function operates in
text mode and a file is opened only for reading. The verbose equivalent of what we did above is:
>>> fobject = open('linuxconfig.txt', 'rt')
The second argument of the function is the
mode. In this case,
'rt', where the
'r' stands for
read and the
't' specifies that we are operating in text mode. It’s also possible to open files in binary mode, replacing
'b': in this case bytes content, without any encoding will be returned. Since
't' is the default mode, from now on, we will omit it. To read the content of the file we can use, for example, the
read method. It will return all the file content as a string:
>>> fobject.read() 'linuxconfig is awesome!\n'
When are operating in read mode, any attempt of writing to the file will raise an
>>> fobject.write('linuxconfig is awesome!') Traceback (most recent call last): File "<stdin>", line 1, in <module> io.UnsupportedOperation: not writable
Obviously, this is not the only mode available. Lets see the others.
Write mode – ‘w’
'w' as the value of the
mode argument of the
open function, if the file exists, it is first
truncated (its entire content is discarded) and then it is opened for writing; if the file doesn’t exists, it is created. In this case we use the
write method of the file object:
>>> fobject = open('linuxconfig.txt', 'w') >>> fobject.write('We just wrote to the file!') 26 >>> fobject.close()
We opened the file for writing, than we used the
write method of the file object, which writes the string and returns the number of characters written, 26 in this case, finally we used the
close method to close the object: this step is really important, since the write operation becomes effective only once the content of the file is flushed (we will see the importance of closing a file object at the end of the tutorial). If we now examine the content of the file, we see that its previous content has been overwritten, and it only contains the string:
'We just wrote to the file!'
As happened above, if we try to perform an operation not allowed by the mode of operation, an exception is raised. In this case, if we try to read the content of the file we obtain the following result:
>>> fobject = open('linuxconfig.txt', 'w') >>> fobject.read() Traceback (most recent call last): File "", line 1, in io.UnsupportedOperation: not readable
Appending to a file: ‘a’ mode
What if we want to append to a file, keeping its current content? We have to use the
'a' (append) mode. When this mode is used, if a file exists, it is opened for writing and the stream is positioned at the end of it. This way the previous content of the file, will be preserved. If the file doesn’t exists, it is created:
>>> fobject = open('linuxconfig.txt', 'a') >>> fobject.write('Appended text!') 14 >>> fobject.close()
We opened the file in
'a' mode, and write the ‘Appended text’ string to the file. The previous content has not been truncated:
Linuxconfig is awesome! Appended text!
The ‘x’ mode – exclusive creation
This opening mode is available only in python3. When it is used, a
FileExistsError it’s raised if the file already exists. If the file doesn’t exist, it is created and opened for writing:
fileobject = open('linuxconfig.txt', 'x') Traceback (most recent call last): File "<stdin>", line 1, in <module> FileExistsError: [Errno 17] File exists: 'linuxconfig.txt'
Each time we write something, it is appended to the previous content, until we close the file object:
>>> fileobject = open('linuxconfig1.txt', 'x') >>> fileobject.write('Linuxconfig is awesome again\n') >>> fileobject.write('I repeat: Linuxconfig is awesome!\n') >>> fileobject.close()
After running the above code the new file content will be:
Linuxconfig is awesome! I repeat: Linuxconfig is awesome!
The ‘+’ character
We saw the basic modes which can be used with the
open function and how they work. By appending the
'+' character to each of them, we can obtain new behaviors.
The ‘r+’ mode
When appending the ‘+’ character to the ‘r’ mode (‘r+’), a file is opened both for reading and writing; an exception is raised if the file doesn’t exist. The stream is positioned at the beginning of the file, so if something is written it will override the previous content. If we are in this mode, but still we want the new content to be appended, reserving the existent, we must change the current position using the
seek method of the file object before writing, in the following way:
>>> fileobject = open('linuxconfig.txt', 'r+'): >>> fileobject.seek(0,2) >>> fileobject.write('this text will be appended') >>> fileobject.close()
seek method takes two argument: the first is the
offset, the second is the position from which the offset should be calculated, where
0 (the default if this argument is omitted) is the beginning of the file,
1 is the current offset, and
2 is the end of the file. In this case we used an offset of 0 from the end of the file, therefore moving to the end of the file itself. Notice that specifying a non-zero offset in this case would have raised an
io.UnsupportedOperation exception, since it’s impossible to do a non-zero, end-relative seek.
The ‘w+’ mode
This mode works this way: the file will be opened both for reading and writing. If the file exists its content will be truncated, otherwise the file will be created. Just like the in previous example, it will be possible to read and write the file, however there are two big differences: the first is that the file content will be truncated as soon as it is opened (and not if you active write something to it), the second is that the file will be created if it doesn’t exists.
The ‘a+’ mode
When specifying this mode with the python open function, we obtain the following behavior: just like in the previous examples the file is opened both for reading and for writing, however, the stream is positioned at the end of the file, so any new content it’s appended to the existent.
Two things should be noted: since the stream is positioned at the end of the file, if we try to use the
read method on the file object to get the current content, it will return an empty string. To be able to read the content, we should first move to the beginning of the file, using the seek method in the following way:
The second, very important thing to notice, is that when using this mode, even if we move to the beginning of the file just like we did in the example above, and perform a write, the existing content it’s not lost: the new content it’s always appended.
Closing the file object
After we finished working with our file object, we must always remember to close it, for multiple reasons. In primis because some operations, like writing, become effective only when the file object is closed and its content is flushed, secondarily to free system resources and for code clarity. There are two ways we can close a file object: the first one is by calling the
close method on the file object, as we saw above. The second one, is by using the
with open('linuxconfig.txt', 'r') as fileobject: content = fileobject.read() # perform needed operations
What happens in this case? Using this statement, the expression next to
with, in this case
open('linuxconfig.txt', 'r'), is evaluated into a file object, which supports the context manager protocol, since it implements the
__exit__ methods. The file object is then aliased to
fileobject. After the code contained in the block is executed, the
__exit__ method of the file object is automatically called, and the file object is closed. Using a context manager is really useful, because the object will be always closed as soon as we finish operating on it: one less thing to remember.
In this tutorial we learned how to use the python built-in
open function to create a file object, used to interact with a file. We saw the various modes which can be passed to the function and how they change the behavior of the file object. Finally, we saw why it’s important to always close a file object after we finish working with it, how we can do it by using the
close method, and how it can be done automatically, if we use the
with statement, and a context manager. As always suggested, you can consult the official documentation to further improve your knowledge.