In this chapter, we will cover some options for handling data files. Depending on the data and the desired format, there are several options for reading and writing. We will show some of the most useful alternatives.
File I/O (input and output) is essential in a number of scenarios. For example:
In this section, we will cover how to handle file I/O in Python.
In Python, an object of type file
represents the contents of a physical file stored on disk. A new file
object may be created using the following syntax:
myfile = open('measurement.dat','r') # creating a new file object from an existing file
The contents of the file may be accessed, for instance, with this:
print(myfile.read())
Usage of file objects requires some care. The problem is that a file has to be closed before it can be reread or used by other applications, which is done using the following syntax:
myfile.close() # closes the file object
It is, however, not that simple because an exception might be triggered before the call to close
is executed, which will skip the closing code (consider the following example). A simple way to make sure that a file will be properly closed is to use context managers. This construction, using the with
keyword, is explained in more detail in section Exception in Chapter 10, Error Handling. Here is how it is used with files:
with open('measurement.dat','r') as myfile: ... # use myfile here
This ensures that the file is closed when one exits the with
block, even if an exception is raised inside the block. The command works with context manager objects. We recommend that you read more on context managers in section Exception in Chapter 10, Error Handling. Here is an example showing why the with
construct is desirable:
myfile = open(name,'w') myfile.write('some data') a = 1/0 myfile.write('other data') myfile.close()
An exception is raised before the file is closed. The file remains open, and there is no guarantee of what data is written in the file or when it is written. Hence, the proper way to achieve the same result is this:
with open(name,'w') as myfile: myfile.write('some data') a = 1/0 myfile.write('other data')
In that case, the file is cleanly closed just after the exception (here, ZeroDivisionError
) is raised. Notice also that there is no need to close the file explicitly.
A file is, in particular, iterable (refer to section Iterators of Chapter 9, Iterating). Files iterate their lines:
with open(name,'r') as myfile: for line in myfile: data = line.split(';') print('time {} sec temperature {} C'.format(data[0],data[1]))
The lines of the file are returned as strings. The string method split
is a possible tool to convert the string to a list of strings. For example:
data = 'aa;bb;cc;dd;ee;ff;gg' data.split(';') # ['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg'] data = 'aa bb cc dd ee ff gg' data.split(' ') # ['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg']
Since the myfile
object is iterable, we can also do a direct extraction into a list, as follows:
data = list(myfile)
As you can see in these examples of file handling, the open
function takes at least two arguments. The first is obviously the filename, and the second is a string describing the way in which the file will be used. There are several such modes for opening files; the basic ones are:
with open('file1.dat','r') as ... # read only with open('file2.dat','r+') as ... # read/write with open('file3.dat','rb') as ... # read in byte mode with open('file4.dat','a') as ... # append (write to the end of the file) with open('file5.dat','w') as ... # (over-)write the file with open('file6.dat','wb') as ... # (over-)write the file in byte mode
The 'r'
, 'r+'
, and 'a'
modes require that the file exists, whereas 'w'
will create a new file if no file with that name exists. Reading and writing with 'r'
and 'w'
is most common, as you saw in previous examples.
Consider an example of opening a file and adding data at the end of the file without modifying what is already there using the append 'a'
mode. Note the line break,
:
with open('file3.dat','a') as myfile: myfile.write('something new ')
3.133.157.142