File handling
open function
- syntax: open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
>>> import locale
>>> locale.getpreferredencoding()
'UTF-8'
- We'll be seeing these modes in this chapter
r
open file for readingw
open file for writinga
open file for appending
- default is text mode, so passing 'r' and 'rt' are equivalent
- for binary mode, it would be 'rb', 'wb' and so on
locale.getpreferredencoding()
gives default encoding being used- Python docs - open
- Python docs - standard encodings
Reading files
#!/usr/bin/python3
# open file, read line by line and print it
filename = 'hello_world.py'
f = open(filename, 'r', encoding='ascii')
print("Contents of " + filename)
print('-' * 30)
for line in f:
print(line, end='')
f.close()
# 'with' is a simpler alternative, automatically handles file closing
filename = 'while_loop.py'
print("\n\nContents of " + filename)
print('-' * 30)
with open(filename, 'r', encoding='ascii') as f:
for line in f:
print(line, end='')
- default encoding is usually 'UTF-8', use 'ascii' where applicable
- using
with
and file handle name asf
is usual convention
$ ./file_reading.py
Contents of hello_world.py
------------------------------
#!/usr/bin/python3
print("Hello World")
Contents of while_loop.py
------------------------------
#!/usr/bin/python3
# continuously ask user input till it is a positive integer
usr_string = 'not a number'
while not usr_string.isnumeric():
usr_string = input("Enter a positive integer: ")
If file doesn't exist
#!/usr/bin/python3
with open('xyz.py', 'r', encoding='ascii') as f:
for line in f:
print(line, end='')
- Error if file is not found
$ ./file_reading_error.py
Traceback (most recent call last):
File "./file_reading_error.py", line 3, in <module>
with open('xyz.py', 'r', encoding='ascii') as f:
FileNotFoundError: [Errno 2] No such file or directory: 'xyz.py'
$ echo $?
1
- read entire file content as single string using
read()
>>> f = open('hello_world.py', 'r', encoding='ascii')
>>> f
<_io.TextIOWrapper name='hello_world.py' mode='r' encoding='ascii'>
>>> print(f.read())
#!/usr/bin/python3
print("Hello World")
- read line by line using
readline()
>>> f = open('hello_world.py', 'r', encoding='ascii')
>>> print(f.readline(), end='')
#!/usr/bin/python3
>>> print(f.readline(), end='')
>>> print(f.readline(), end='')
print("Hello World")
>>> f.close()
>>> print(f.readline(), end='')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: I/O operation on closed file.
- read all lines of file as list using
readlines()
- note the plural form
>>> f = open('hello_world.py', 'r', encoding='ascii')
>>> all_lines = f.readlines()
>>> all_lines
['#!/usr/bin/python3\n', '\n', 'print("Hello World")\n']
- check if file is closed or not
>>> f = open('hello_world.py', 'r', encoding='ascii')
>>> f.closed
False
>>> f.close()
>>> f.closed
True
Writing to files
#!/usr/bin/python3
with open('new_file.txt', 'w', encoding='ascii') as f:
f.write("This is a sample line of text\n")
f.write("Yet another line\n")
- Use the
write()
method to print a string to files - To add text to an existing file, use 'a' mode instead of 'w'
$ ./file_writing.py
$ cat new_file.txt
This is a sample line of text
Yet another line
Inplace editing with fileinput
#!/usr/bin/python3
import fileinput
with fileinput.input(inplace=True) as f:
for line in f:
line = line.replace('line of text', 'line')
print(line, end='')
- The files to be modified are specified as Command line arguments when the program is run
- Note that
print
function has to be used instead off.write
- Since the line read every iteration already has newline character, end is assigned empty string
- Python docs - fileinput
$ ./inplace_file_editing.py new_file.txt
$ cat new_file.txt
This is a sample line
Yet another line
$ # to change all files in current directory ending with .txt, use
$ ./inplace_file_editing.py *.txt
$ # stdin can also be passed as input, inplace gets disabled
$ echo 'a line of text' | ./inplace_file_editing.py
a line
- specifying filenames and backup extensions
# To specify filenames within the program itself
with fileinput.input(inplace=True, files=('file1.txt', 'file2.txt')) as f:
# To create backup of unmodified files, pass an extension to backup parameter
with fileinput.input(inplace=True, backup='.bkp') as f: