Working with files in Python
Introduction
In this article you will learn how to organise working with files in Python 3.
Create the file
files.py
and copy the code from the examples into it.
You can run the file with the command
python3 files.py
Create
You can create a file with the command
open
Options:
r read
rb reading in binary mode
w write only.
wb writing in binary mode
w+ write and read
a write to the end of the file - keeps the data that was in the file
Any option with w will overwrite the existing file - be careful!
Example:
f = open("log.txt","w+")
Open the file
To open a file for reading, execute
f = open("log.txt","r")
If the file log.txt does not exist, it will not be created
raceback (most recent call last): File "files.py", line 1, in <module> f = open('log.txt', 'r') FileNotFoundError: [Errno 2] No such file or directory: 'log.txt'
Close the file
To close the file, execute
f.close()
File name
An example program that prints the name of the file and the mode in which it is open
f = open('text.txt', 'r')
print(f.name)
print(f.mode)
f.close()
If the file log.txt exists, then in the terminal you will see
text.txt
r
Context manager
It is preferable to use a context manager for working with files
As soon as you leave the block in which the file is open, it is closed automatically
with open('text.txt', 'r') as f:
pass
print(f.closed)
True
Read the contents of the file
with open('sites.txt', 'r') as f:
f_contents = f.read()
print(f_contents)
www.eth1.ru www.heihei.ru www.topbicycle.ru
All lines with a newline character - readlines
with open('sites.txt', 'r') as f:
f_contents = f.readlines()
print(f_contents)
['www.eth1.ru\n', 'www.heihei.ru\n', 'www.topbicycle.ru\n']
Lines one by one readline
with open('sites.txt', 'r') as f:
f_contents = f.readline()
print(f_contents)
f_contents = f.readline()
print(f_contents)
www.eth1.ru www.heihei.ru
Lines one by one without extra newlines end=''
with open('sites.txt', 'r') as f:
f_contents = f.readline()
print(f_contents, end = '')
f_contents = f.readline()
print(f_contents, end = '')
www.eth1.ru www.heihei.ru
A loop for printing line by line
with open('sites.txt', 'r') as f:
for line in f:
print(line, end = '')
www.eth1.ru www.heihei.ru www.topbicycle.ru
Read a certain number of characters
with open('sites.txt', 'r') as f:
f_contents = f.read(20)
print(f_contents)
www.eth1.ru www.heihe
If you run this command consecutively, the following characters are read
with open('sites.txt', 'r') as f:
f_contents = f.read(20)
print(f_contents, end = '')
f_contents = f.read(20)
print(f_contents, end = '')
www.eth1.ru www.heihei.ru www.topbicycle.
A loop for an arbitrary number of characters with .read
with open('sites.txt', 'r') as f:
size_to_read = 10
f_contents = f.read(size_to_read)
while len(f_contents) > 0:
print(f_contents, end = '')
f_contents = f.read(size_to_read)
www.eth1.ru www.heihei.ru www.topbicycle.ru
The expression f_contents = f.read(size_to_read) is needed so that when the file ends and f.read(size_to_read) becomes zero, len(f_contents) also becomes zero and the loop finishes
Go to an arbitrary place
seek
For example, return to the beginning of the file
f.seek(0)
Copying files
Text files
They can be copied line by line
with open('sites.txt', 'r') as rf:
with open('sites_copy.txt', 'w') as wf:
for line in rf:
wf.write(line)
cat sites_copy.txt
www.eth1.ru www.heihei.ru www.topbicycle.ru
Images
They can also be copied line by line, but they must be opened and written in binary mode. That is, you need to add the option b
Download an image of a bicycle from the site
TopBicycle.ru
or take any other picture
wget https://topbicycle.ru/b/img/stels_pilot_950_MD_26.jpg
ls
stels_pilot_950_MD_26.jpg
with open('stels_pilot_950_MD_26.jpg', 'rb') as rf:
with open('stels_pilot_950_MD_26_copy.jpg', 'wb') as wf:
for line in rf:
wf.write(line)
python3 files.py
ls
stels_pilot_950_MD_26.jpg stels_pilot_950_MD_26_copy.jpg
Copying not line by line but in chunks of a fixed size is considered a more correct approach
with open('stels_pilot_950_MD_26.jpg', 'rb') as rf:
with open('stels_pilot_950_MD_26_copy.jpg', 'wb') as wf:
chunk_size = 4096
rf_chunk = rf.read(chunk_size)
while len(rf_chunk) > 0:
wf.write(rf_chunk)
rf_chunk = rf.read(chunk_size)
Write to a file
To clear the file of its old contents and write a new one into it, the option is used: w (write)
with open('log.txt', 'w') as f:
f.write("some text")
Append to a file
If you need to add new data to the previous contents without deleting them, the option is used: a (append)
with open('log.txt', 'a') as f:
f.write("some text")
Write json to a file
import json
need to get json from somewhere
r = urllib.request.urlopen('http://eth1.ru/api/v1/getjson')
rr = r.read()
rj = json.loads(rr)
with open('file.txt', 'w') as f:
json.dump(rj, f)
Delete the first few lines of a file
with open('log.txt', 'a') as fin:
data = fin.readlines()[1:]
with open('new.txt', 'w') as fout:
fout.writelines(data)
Writing the program output to a file
If you run the script from the terminal, use redirection
python script.py > script.log
In the script itself you can temporarily replace the standard output.
Suppose I make a request to an API
(More about REST API)
import sys … # Keep a reference to the original stdout original_stdout = sys.stdout with open("log.txt", "a") as f: sys.stdout = f print(resp.data) sys.stdout = original_stdout
The same applies if what arrives is json and you want to write it out nicely
import sys import json … with open("log.txt", "a") as f: sys.stdout = f print(json.dumps(resp.data, indent=4)) sys.stdout = original_stdout
Article author: Andrei Olegovich