Files provide a way to store, manipulate, and present data in a variety of ways. A text file is one of the most basic file types and is stored in a plain text format, meaning there are no special formatting or data conversion needed for the file. Python provides straightforward ways of handling text files.

The  open() function

The builtin open() function is used to open a file for reading or writing. It takes two arguments path and mode,  it returns a file object.

Syntax:
open(path, mode)

the path argument specifies the path(relative or absolute) to the file that we want to open. The mode argument specifies the mode in which the file should be opened. The mode can be 'r' for reading, 'w' for writing, 'a' for appending,  'x' for exclusive creation, and others. 

reading data from a file

I have a  file in my working directory named demo.txt which contains the following data:

Japan
France
Brazil
India
Italy
Australia
Mexico
South Africa
Russia
Canada
Indonesia
Germany
Spain
Thailand
China

Specifying  'r' as the mode, makes the opened file a read only meaning that we cannot write any data to it

ExampleEdit & Run
file = open('demo.txt', 'r')
print(file)
file.close()
Output:

<_io.TextIOWrapper name='demo.txt' mode='r' encoding='cp1252'>

Note: You should provide the full path(relative or absolute) to the file if it is not located at the same directory as your Python script or you are not running the interpreter at the directory where the file is located.

If the file with the specified path does not exist, a FileNotFoundError error will be raised.

It is important to close a file when we are done using it to ensure that any resources it may have been using are released. The close() method, as shown above, is used to close the file and release any resources associated with it. However, the open function supports use with the with statement, this way, we can omit the statement to close the file and the file will be closed automatically in the background.  For example:  

ExampleEdit & Run
with open('demo.txt', 'r') as file:
    print(file)
Output:

<_io.TextIOWrapper name='demo.txt' mode='r' encoding='cp1252'>

Using the with keyword is considered a good practice as one might forget to call the close() method explicitly. We will be using the with statement from here onward.

We can perform some general file operations such as checking the name of the opened file, checking whether it is writable, checking the mode used to open the file, etc.

ExampleEdit & Run
with open('demo.txt', 'r') as file:
   print(file.name)#name of the file
   print(file.mode)#mode used in opening
   print(file.writable())#is the file writable?
   print(file.closed)#is the file closed?
Output:

demo.txt
r
False
False

To actually read the data from the file object into the program, we use the following methods of the file object:

  • read()
Syntax:
file.read(size)

size is an optional parameter that specifies the maximum number of bytes to be read from the file. If size is not specified or is negative, the entire file is read. 

ExampleEdit & Run
with open('demo.txt', 'r') as file:
    data = file.read()
    print(r''+ data)
    print(data)
Output:

'Japan\nFrance\nBrazil\nIndia\nItaly\nAustralia\nMexico\nSouth Africa\nRussia\nCanada\nIndonesia\nGermany\nSpain\nThailand\nChina'
Japan
France
Brazil
India
Italy
Australia
Mexico
South Africa
Russia
Canada
Indonesia
Germany
Spain
Thailand
China

  • readline()

The readline() method reads a single line of a file at a time and returns a string containing the characters in the line . It takes an optional argument that allows you to specify the maximum number of bytes to read. If the argument is omitted, readline() will read up to the end of the current line. The pointer is moved to the beginning of the next line after each call so that successive calls will return successive lines.

ExampleEdit & Run
with open('demo.txt', 'r') as file:
    file.readline()
    file.readline()
    file.readline()
    file.readline()
    file.readline()
Output:

'japan\n'
'France\n'
'Brazil\n'
'India\n'
'Italy\n' 

  • readlines()

The readlines() method reads the file object line by line including the new line characters in the lines, it returns  a list containing all the lines in .  The list can then be traversed line by line or manipulated as per the requirement. Examples:

ExampleEdit & Run
with open('demo.txt', 'r') as file:
    L = file.readlines()
    print(L)
    L = [i.replace('\n', '') for i in L]#remove new line characters from the lines
    print(L)
Output:

['Japan\n', 'France\n', 'Brazil\n', 'India\n', 'Italy\n', 'Australia\n', 'Mexico\n', 'South Africa\n', 'Russia\n', 'Canada\n', 'Indonesia\n', 'Germany\n', 'Spain\n', 'Thailand\n', 'China']
['Japan', 'France', 'Brazil', 'India', 'Italy', 'Australia', 'Mexico', 'South Africa', 'Russia', 'Canada', 'Indonesia', 'Germany', 'Spain', 'Thailand', 'China']

Since the readlines() method includes the end of line characters, a more elegant approach to getting all the lines into a list would be to use the read() method and the splitlines() method of strings, as shown below:

ExampleEdit & Run
with open('demo.txt', 'r') as file:
    L = file.read().splitlines()
    print(L)
Output:

['Japan', 'France', 'Brazil', 'India', 'Italy', 'Australia', 'Mexico', 'South Africa', 'Russia', 'Canada', 'Indonesia', 'Germany', 'Spain', 'Thailand', 'China']

The above approach is also more efficient than using the readlines() method.

Writing to a File

The 'w' mode opens the specified file for writing and creates a new file  if it does not already exist. This mode overwrites the existing content in the file with the new information so it is important to take care when using the 'w' mode to prevent data loss.

The write() method

The write() method  is used to write a string to a file, It takes one argument, which is a string, and writes it to the specified file.

Syntax:
fileObject.write(string) 
ExampleEdit & Run
with open("demo.txt", "w") as file:
    file.write('Japan\nFrance\nBrazil\n')

As we said earlier, all the data in the file 'demo.txt' will be overwritten, and if the file does not exist new file with that name will be created. 

populating data from a list into 'demo.txt'

ExampleEdit & Run
data = ['Japan', 'France', 'Brazil', 'India', 'Italy', 'Australia', 'Mexico', 'South Africa', 'Russia', 'Canada', 'Indonesia', 'Germany', 'Spain', 'Thailand', 'China']
with open('demo.txt', 'w') as file:
    data_string = '\n'.join(data)
    file.write(data_string)

The above program will repopulate our initial data into 'demo.txt'.

We can also use the writelines() method which writes data from an iterable to the file. example:

ExampleEdit & Run
with open('demo.txt', 'w') as file:
    data = ['Japan\n', 'France\n', 'Brazil\n', 'India\n', 'Italy\n', 'Australia\n', 'Mexico\n', 'South Africa\n', 'Russia\n', 'Canada\n', 'Indonesia\n', 'Germany\n', 'Spain\n', 'Thailand\n', 'China\n']
    file.writelines(data)

Lastly, the print() function takes an optional argument, file, which specifies the file where the print values will go. if a file object is passed as this argument, the values will be written to the opened file. 

ExampleEdit & Run
with open('demo.txt', 'w') as file:
    data = ('Japan', 'France', 'Brazil', 'India', 'Italy', 'Australia', 'Mexico', 'South Africa', 'Russia', 'Canada', 'Indonesia', 'Germany', 'Spain', 'Thailand', 'China')
    print(*data, sep='\n', file = file)

The 'x' mode for exclusive creation opens the file for writing same as 'w' mode, but raises a FileExistsError if the file already exists.

Appending to a File

The 'a' mode indicates that the file is open for appending meaning that you are able to add content to the end of the file without overwriting any existing content. We  can still use the write() and the writelines() methods as well as the print() function in this mode.

Let us add more countries to the end of the 'demo.txt' using the various methods.

ExampleEdit & Run
with open('demo.txt', 'a') as file:
    more_countries = ['Kenya', 'Norway', 'Austria', 'Canada', 'Rwanda']
    file.write('\n'.join(more_countries))
    more_countries = ['Fiji\n', 'Uruguay\n', 'Tajikistan\n', 'Tunisia\n']
    file.writelines(more_countries)
    more_countries = ['Madagascar', 'Croatia', 'Lebanon', 'Bolivia', 'Mongolia']
    for i in more_countries:
        print(i, sep='\n',file = file)

Text Opening Modes Summary

mode name usage
'r' Read Used to only read data from the file.
'w' Write Used to write data into the file or modify it. Remember write mode overwrites the data present in the file.
'a' Append  Used to append data to the file. Remember data will be appended at the end of the file pointer.
'x' exclusive creation Similar to opening the file in 'w' mode, except that an error is raised if a file with the specified name already exists
'r+' Read or Write Used to write or read the data from the same file
'a+' Append or Read Used to read data from the file or append the data into the same file.

Note: You can optionally add a 't' at the end of the modes to explicitly state that the file is being opened in text mode. For example, 'rt' , 'wt' and 'at+'  are equivalent to 'r' 'w' and 'a+' respectively.