Skip to content

Щоб не загрузити пам`ять треба читати з файлу по одному рядку: Краще так:

with open("somefile.txt", "r") as file:
    for line in file:
        print(line)

(file.close() не треба бо використовується контекст менеджер а також виключається можливість помилок якщо файл завеликий, бо читання йде построково)

Запис:

with open("somefile.txt", "w") as file:
    file.write("something")

Example:

with (open(args_list[1], "r") as read_file,  
     open(args_list[2], "a") as write_file):  
    for line in read_file:  
        write_file.write(line)

Function open and close

File Handling

In this lesson, we will look at why we need files and how to work with them.

File Usage

Sometimes we have to work with files. For example, when there is a need for long-term storage of program execution information. It is especially useful if you run your program regularly. It is necessary to record and log whether it started and worked or did not work correctly and ended. One of the solutions to the problem of long-term storage of information is to record it in a file. But, you need to understand that if there is a possibility of writing to a file, there should also be a possibility of reading this file, editing, or deleting it.

Actions with Files

Now, we will consider the actions available for working with files in Python.

Opening Modes

Before starting to work with a file and perform actions on it, it is necessary to open it. You can do it using the built-in open() method. In round brackets, we first write the path to the file and then the mode in which we want to open the file.

If you do not specify the mode, it will automatically open in the default trmode which means reading in text mode.

Let's consider what file modes exist:

  • r — reads the file and returns an error if the file does not exist;
  • w — writes data to a file and creates a new file if it does not exist or overwrites the existing file;
  • a — appends data to a file, and creates the file if it does not exist, or adds new information at the end of the existing file;
  • x — writes data to a file and returns an error if the file already exists (exclusive creation);
  • t — is used only for textual files (text mode — we see the text);
  • b — is used for non-textual files, such as images, videos, etc. (binary mode — we see 0 and 1);
  • + — allows to work in the read and write modes simultaneously.

And now, let's look at how it works. Let us have an "errors.txt" file that contains the following data:

10:53 12/09/2022 too many requests
21:17 13/09/2022 user admin not found

We can open this file as follows:

file = open("errors.txt")

In this example, the file was opened in the default tr mode since we did not specify which mode we needed.

Now let's open this same file in the read mode:

file = open("errors.txt", "r")

Please note: there is no difference between r and tr modes since the text mode is the default.

Closing

So far, we have only learned how to open files, but closing them is a mandatory procedure when working with files.

Imagine that you have launched a large project that often writes information to a file. Next, you forgot to close the file, and the program continues to work even if you no longer need to write to the file.

After some time, the file will be filled with unnecessary information, and a large amount of computer memory will be occupied by this information, leading to system errors. To avoid such a scenario, be sure to close the file after use.

You can do it with the built-in close() method. Here's an example of how it works:

file = open("errors.txt", "r")
file.close()

Reading

To read the entire file into one variable, use the read() method.

file = open("errors.txt", "r")

print(file.read())
# 10:53 12/09/2022 too many requests
# 21:17 13/09/2022 user admin not found

file.close() # And do not forget to close your file

If you pass a numeric argument to the read() method, it will return the specified number of characters from the file:

file = open("errors.txt", "r")
print(file.read(10))    # 10:53 12/0
file.close()

To start reading not from the file beginning, use the seek() method and specify inside the number of needed skipped symbols:

file = open("errors.txt", "r")

file.seek(10)
print(file.read())
# 9/2022 too many requests
# 21:17 13/09/2022 user admin not found

file.close()

To read your file line by line, create a loop and use the readline() or readlines() method. The readline() method returns a line from the file when called and readlines() method returns all the lines in a file as a list where each element is a line in the file. For example:

file = open("errors.txt", "r")

print("Readline method working")
print(file.readline())

file.close()

In the console you will see:

Readline method working
10:53 12/09/2022 too many requests

And the example of readlines() method:

file = open("errors.txt", "r")

line_number = 1     # Variable for seeing the number of a line 
print("Readlines method working")
for line in file.readlines():
    print(f"Line number {line_number}")
    print(line)
    line_number += 1

file.close()

In the console you will see:

Readlines method working
Line number 1
10:53 12/09/2022 too many requests
Line number 2
21:17 13/09/2022 user admin not found

An interesting part of these methods is that here we won't have problems with memory — at one moment, we read only 1 line from the file, but not the whole file, as with the read() method. So, even if the file is huge, we may still process it reading line by line (yes, it may be a long process, but still, we can).

Another way to read line by line is to iterate over it using the for loop without any additional methods:

file = open("errors.txt", "r")

line_number = 1     # Variable for seeing the number of a line 
for line in file:
    print(f"Line number {line_number}")
    print(line)
    line_number += 1

file.close()

In the console you will see:

Line number 1
10:53 12/09/2022 too many requests
Line number 2
21:17 13/09/2022 user admin not found

Writing and Appending

To write information to a file, use the w — write mode. Opening a file in write mode creates a new file if it does not exist or overwrites an existing file. One of the ways to write information to a file is the built-in write() method.

Please note: only strings can be passed to the write() method as arguments:

file = open("errors.txt", "w")
file.write("17:00 14/09/2022 value error")

file.close()

Now the "errors.txt" file contains the "17:00 14/09/2022 value error" string. The old information from the file was overwritten by the new one.

To append some data to a file without losing the existing information, we need to open the file with the a — append mode. This mode creates the file if it does not exist or adds new information at the end of the existing file. To write information to a file, also use the write() method:

file = open("errors.txt", "a")
file.write("17:00 14/09/2022 value error")

file.close()

Now, if we read the file, in the console we will see:

10:53 12/09/2022 too many requests
21:17 13/09/2022 user admin not found
17:00 14/09/2022 value error

You can see the difference between the write and append modes in these examples. In the first example, the existing information was replaced with new information. In the second example, the new information was written after the existing information at the end of the file.

Context Managers in Files

But what happens if you forget to close the file after opening it? It is better for us not to find out. Python can prevent this. For that — use the context managers.

Context managers are often associated with the with statement. By wrapping work with a file in a context manager — it will close the file automatically when exiting that scope.

Let's look at two similar examples:

# Solution 1

file = open("errors.txt", "r")
# Some actions with file
file.close()


# Solution 2

with open("errors.txt", "r") as file:
    # Some actions with file

As you can see in these two solutions, the file is opened and closed. But the second case takes up less space, looks more elegant, and guarantees to close the file even if you forget about it.

You should always use context managers because when an error occurs between opening and closing the file, the program ends, but the context manager will close the file even if an error occurs.

For example, this file will be closed:

with open("errors.txt", "w+") as file:
    file.read()
    file.write(1/0)

Please note: context manager works not only with files. Different examples of its use will be considered further in other topics.

The main points to remember when working with the context managers:

  1. The context manager always contains two special methods: __enter__and __exit__.
  2. The __enter__ method returns an object assigned to a variable after the as keyword. The default value is None and it is optional.
  3. If an error occurs in __init__ or __enter__, then the code block is never executed and the __exit__ is not called.
  4. After entering into a block of code, the __exit__ is always called, even if an exception occurs in it.

It is a context manager structure:

class CustomContextManager():
    def __init__(self):
        pass

    def __enter__(self):
        pass

    def __exit__(self):
        pass

    def __del__(self):
        pass

Context Managers

Як влаштований :

with open("filename.txt", "r") as f:
    f.read()

Приблизно так: