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

Software Requirements and Linux Command Line Conventions
Category Requirements, Conventions or Software Version Used
System OS-independent
Software python3
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 sudo command
$ - 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

rpm

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 file objects.



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 write and 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 't' with '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 io.UnsupportedOperation exception:

>>> 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'

When specifying '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, preserving 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()

The 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:

fileobject.seek(0)

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 statement:

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 __enter__ and __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.

Conclusions

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.

See also our more extensive python tutorial for more python related concepts or our Reading and Writing files with Python guide.

ARE YOU LOOKING FOR A LINUX JOB?
Submit your RESUME or create a JOB ALERT on LinuxCareers.com job portal.
DO YOU NEED ADDITIONAL HELP?
Get extra help by visiting our LINUX FORUM or simply use comments below.

You may also be interested in:



Comments and Discussions