Конец файла Python

EOF означает End Of File . Это момент в программе, когда пользователь больше не может читать данные. Это означает, что программа читает весь файл до конца. Кроме того, при достижении EOF или конца файла в качестве вывода возвращаются пустые строки. Итак, пользователю необходимо знать, находится ли файл в его EOF.
Please enable JavaScript
В этом руководстве представлены различные способы узнать, находится ли файл в его EOF в Python.
Используйте file.read() , чтобы найти конец файла в Python
Метод file.read() — это встроенная функция Python, используемая для чтения содержимого данного файла. Если метод file.read() возвращает пустую строку в качестве вывода, это означает, что файл достиг своего EOF.
Обратите внимание, что когда мы вызываем функцию open() для открытия файла при запуске программы, мы используем «r» как режим только для чтения файла. Наконец, мы используем условный оператор if , чтобы проверить, что возвращаемый результат — это пустая строка.
Используйте метод readline() с циклом while для поиска конца файла в Python
Метод file.readline() — еще одна встроенная функция Python для чтения одной полной строки текстового файла.
Цикл while в Python — это цикл, который повторяет данное условие в блоке кода до тех пор, пока данное условие не станет истинным. Этот цикл используется, когда количество итераций заранее не известно.
Использование цикла while с методом readline() помогает многократно читать строки в данном текстовом файле.
Цикл while прекратит итерацию, когда в текстовом файле не останется текста для чтения методом readline() .
Использование оператора Walrus для поиска конца файла в Python
Оператор Walrus — новый оператор в Python 3.8. Обозначается := . Этот оператор по сути является оператором присваивания, который используется для присвоения значений True и их немедленной печати.
Здесь значения True — это символы, которые функция read() будет читать из текстового файла. Это означает, что оператор моржа прекратит печать после завершения файла.
EOF — это не символ
Недавно я читал книгу «Компьютерные системы: архитектура и программирование. Взгляд программиста». Там, в главе про систему ввода-вывода Unix, авторы упомянули о том, что в конце файла нет особого символа EOF .

Если вы читали о системе ввода-вывода Unix/Linux, или экспериментировали с ней, если писали программы на C, которые читают данные из файлов, то это заявление вам, вероятно, покажется совершенно очевидным. Но давайте поближе присмотримся к следующим двум утверждениям, относящимся к тому, что я нашёл в книге:
- EOF — это не символ.
- В конце файлов нет некоего особого символа.
EOF — это не символ
Почему кто-то говорит или думает, что EOF — это символ? Полагаю, это может быть так из-за того, что в некоторых программах, написанных на C, можно найти код, в котором используется явная проверка на EOF с использованием функций getchar() и getc() .
Это может выглядеть так:
Если заглянуть в справку по getchar() или getc() , можно узнать, что обе функции считывают следующий символ из потока ввода. Вероятно — именно это является причиной возникновения заблуждения о природе EOF . Но это — лишь мои предположения. Вернёмся к мысли о том, что EOF — это не символ.
А что такое, вообще, символ? Символ — это самый маленький компонент текста. «A», «a», «B», «b» — всё это — разные символы. У символа есть числовой код, который в стандарте Unicode называют кодовой точкой. Например — латинская буква «A» имеет, в десятичном представлении, код 65. Это можно быстро проверить, воспользовавшись командной строкой интерпретатора Python:
Или можно взглянуть на таблицу ASCII в Unix/Linux:

Выясним, какой код соответствует EOF , написав небольшую программу на C. В ANSI C константа EOF определена в stdio.h , она является частью стандартной библиотеки. Обычно в эту константу записано -1 . Можете сохранить следующий код в файле printeof.c , скомпилировать его и запустить:
Скомпилируем и запустим программу:
У меня эта программа, проверенная на Mac OS и на Ubuntu, сообщает о том, что EOF равняется -1 . Есть ли какой-нибудь символ с таким кодом? Тут, опять же, можно проверить коды символов в таблице ASCII, можно взглянуть на таблицу Unicode и узнать о том, в каком диапазоне могут находиться коды символов. Мы же поступим иначе: запустим интерпретатор Python и воспользуемся стандартной функцией chr() для того, чтобы она дала бы нам символ, соответствующий коду -1 :
Как и ожидалось, символа с кодом -1 не существует. Значит, в итоге, EOF , и правда, символом не является. Переходим теперь ко второму рассматриваемому утверждению.
В конце файлов нет некоего особого символа
Может, EOF — это особенный символ, который можно обнаружить в конце файла? Полагаю, сейчас вы уже знаете ответ. Но давайте тщательно проверим наше предположение.
Возьмём простой текстовый файл, helloworld.txt, и выведем его содержимое в шестнадцатеричном представлении. Для этого можно воспользоваться командой xxd :
Как видите, последний символ файла имеет код 0a . Из таблицы ASCII можно узнать о том, что этот код соответствует символу nl , то есть — символу новой строки. Это можно выяснить и воспользовавшись Python:
Так. EOF — это не символ, а в конце файлов нет некоего особого символа. Что же такое EOF ?
Что такое EOF?
EOF (end-of-file) — это состояние, которое может быть обнаружено приложением в ситуации, когда операция чтения файла доходит до его конца.
Взглянем на то, как можно обнаруживать состояние EOF в разных языках программирования при чтении текстового файла с использованием высокоуровневых средств ввода-вывода, предоставляемых этими языками. Для этого напишем очень простую версию cat , которая будет называться mcat . Она побайтно (посимвольно) читает ASCII-текст и в явном виде выполняет проверку на EOF . Программу напишем на следующих языках:
- ANSI C
- Python 3
- Go
- JavaScript (Node.js)
ANSI C
Начнём с почтенного C. Представленная здесь программа является модифицированной версией cat из книги «Язык программирования C».
Вот некоторые пояснения, касающиеся вышеприведённого кода:
- Программа открывает файл, переданный ей в виде аргумента командной строки.
- В цикле while осуществляется копирование данных из файла в стандартный поток вывода. Данные копируются побайтово, происходит это до тех пор, пока не будет достигнут конец файла.
- Когда программа доходит до EOF , она закрывает файл и завершает работу.
Python 3
В Python нет механизма явной проверки на EOF , похожего на тот, который имеется в ANSI C. Но если посимвольно читать файл, то можно выявить состояние EOF в том случае, если в переменной, хранящей очередной прочитанный символ, будет пусто:
Запустим программу и взглянём на возвращаемые ей результаты:
Вот более короткая версия этого же примера, написанная на Python 3.8+. Здесь используется оператор := (его называют «оператор walrus» или «моржовый оператор»):
Запустим этот код:
В Go можно явным образом проверить ошибку, возвращённую Read(), на предмет того, не указывает ли она на то, что мы добрались до конца файла:
JavaScript (Node.js)
В среде Node.js нет механизма для явной проверки на EOF . Но, когда при достижении конца файла делается попытка ещё что-то прочитать, вызывается событие потока end.
Низкоуровневые системные механизмы
Как высокоуровневые механизмы ввода-вывода, использованные в вышеприведённых примерах, определяют достижение конца файла? В Linux эти механизмы прямо или косвенно используют системный вызов read(), предоставляемый ядром. Функция (или макрос) getc() из C, например, использует системный вызов read() и возвращает EOF в том случае, если read() указывает на возникновение состояния достижения конца файла. В этом случае read() возвращает 0 . Если изобразить всё это в виде схемы, то получится следующее:

Получается, что функция getc() основана на read() .
Напишем версию cat , названную syscat , используя только системные вызовы Unix. Сделаем мы это не только из интереса, но и из-за того, что это вполне может принести нам какую-то пользу.
Вот эта программа, написанная на C:
В этом коде используется тот факт, что функция read() , указывая на достижение конца файла, возвращает 0 .
SyntaxError Unexpected EOF While Parsing Python Error [Solved]

Ihechikara Vincent Abba
![SyntaxError Unexpected EOF While Parsing Python Error [Solved]](https://www.freecodecamp.org/news/content/images/size/w2000/2022/03/solve.jpg)
Error messages help us solve/fix problems in our code. But some error messages, when you first see them, may confuse you because they seem unclear.
One of these errors is the «SyntaxError: unexpected EOF while parsing» error you might get in Python.
In this article, we’ll see why this error occurs and how to fix it with some examples.
How to Fix the “SyntaxError: Unexpected EOF While Parsing” Error
Before we look at some examples, we should first understand why we might encounter this error.
The first thing to understand is what the error message means. EOF stands for End of File in Python. Unexpected EOF implies that the interpreter has reached the end of our program before executing all the code.
This error is likely to occur when:
- we fail to declare a statement for loop ( while / for )
- we omit the closing parenthesis or curly bracket in a block of code.
Have a look at this example:
In the code above, we created a dictionary but forgot to add > (the closing bracket) – so this is certainly going to throw the «SyntaxError: unexpected EOF while parsing» error our way.
After adding the closing curly bracket, the code should look like this:
This should get rid of the error.
Let’s look at another example.
In the while loop above, we have declared our variable and a condition but omitted the statement that should run until the condition is met. This will cause an error.
Here is the fix:
Now our code will run as expected and print the values of i from 1 to the last value of i that is less than 11.
This is basically all it takes to fix this error. Not so tough, right?
To be on the safe side, always enclose every parenthesis and braces the moment they are created before writing the logic nested in them (most code editors/IDEs will automatically enclose them for us).
Likewise, always declare statements for your loops before running the code.
Conclusion
In this article, we got to understand why the «SyntaxError: unexpected EOF while parsing» occurs when we run our code. We also saw some examples that showed how to fix this error.
Reading and Writing Files in Python (Guide)
One of the most common tasks that you can do with Python is reading and writing files. Whether it’s writing to a simple text file, reading a complicated server log, or even analyzing raw byte data, all of these situations require reading or writing a file.
In this tutorial, you’ll learn:
- What makes up a file and why that’s important in Python
- The basics of reading and writing files in Python
- Some basic scenarios of reading and writing files
This tutorial is mainly for beginner to intermediate Pythonistas, but there are some tips in here that more advanced programmers may appreciate as well.
Free Bonus: Click here to get our free Python Cheat Sheet that shows you the basics of Python 3, like working with data types, dictionaries, lists, and Python functions.
Take the Quiz: Test your knowledge with our interactive “Reading and Writing Files in Python” quiz. Upon completion you will receive a score so you can track your learning progress over time:
What Is a File?
Before we can go into how to work with files in Python, it’s important to understand what exactly a file is and how modern operating systems handle some of their aspects.
At its core, a file is a contiguous set of bytes used to store data. This data is organized in a specific format and can be anything as simple as a text file or as complicated as a program executable. In the end, these byte files are then translated into binary 1 and 0 for easier processing by the computer.
Files on most modern file systems are composed of three main parts:
- Header: metadata about the contents of the file (file name, size, type, and so on)
- Data: contents of the file as written by the creator or editor
- End of file (EOF): special character that indicates the end of the file
What this data represents depends on the format specification used, which is typically represented by an extension. For example, a file that has an extension of .gif most likely conforms to the Graphics Interchange Format specification. There are hundreds, if not thousands, of file extensions out there. For this tutorial, you’ll only deal with .txt or .csv file extensions.
File Paths
When you access a file on an operating system, a file path is required. The file path is a string that represents the location of a file. It’s broken up into three major parts:
- Folder Path: the file folder location on the file system where subsequent folders are separated by a forward slash / (Unix) or backslash \ (Windows)
- File Name: the actual name of the file
- Extension: the end of the file path pre-pended with a period ( . ) used to indicate the file type
Here’s a quick example. Let’s say you have a file located within a file structure like this:
Let’s say you wanted to access the cats.gif file, and your current location was in the same folder as path . In order to access the file, you need to go through the path folder and then the to folder, finally arriving at the cats.gif file. The Folder Path is path/to/ . The File Name is cats . The File Extension is .gif . So the full path is path/to/cats.gif .
Now let’s say that your current location or current working directory (cwd) is in the to folder of our example folder structure. Instead of referring to the cats.gif by the full path of path/to/cats.gif , the file can be simply referenced by the file name and extension cats.gif .
But what about dog_breeds.txt ? How would you access that without using the full path? You can use the special characters double-dot ( .. ) to move one directory up. This means that ../dog_breeds.txt will reference the dog_breeds.txt file from the directory of to :
The double-dot ( .. ) can be chained together to traverse multiple directories above the current directory. For example, to access animals.csv from the to folder, you would use ../../animals.csv .
Line Endings
One problem often encountered when working with file data is the representation of a new line or line ending. The line ending has its roots from back in the Morse Code era, when a specific pro-sign was used to communicate the end of a transmission or the end of a line.
Later, this was standardized for teleprinters by both the International Organization for Standardization (ISO) and the American Standards Association (ASA). ASA standard states that line endings should use the sequence of the Carriage Return ( CR or \r ) and the Line Feed ( LF or \n ) characters ( CR+LF or \r\n ). The ISO standard however allowed for either the CR+LF characters or just the LF character.
Windows uses the CR+LF characters to indicate a new line, while Unix and the newer Mac versions use just the LF character. This can cause some complications when you’re processing files on an operating system that is different than the file’s source. Here’s a quick example. Let’s say that we examine the file dog_breeds.txt that was created on a Windows system:
This same output will be interpreted on a Unix device differently:
This can make iterating over each line problematic, and you may need to account for situations like this.
Character Encodings
Another common problem that you may face is the encoding of the byte data. An encoding is a translation from byte data to human readable characters. This is typically done by assigning a numerical value to represent a character. The two most common encodings are the ASCII and UNICODE Formats. ASCII can only store 128 characters, while Unicode can contain up to 1,114,112 characters.
ASCII is actually a subset of Unicode (UTF-8), meaning that ASCII and Unicode share the same numerical to character values. It’s important to note that parsing a file with the incorrect character encoding can lead to failures or misrepresentation of the character. For example, if a file was created using the UTF-8 encoding, and you try to parse it using the ASCII encoding, if there is a character that is outside of those 128 values, then an error will be thrown.
Opening and Closing a File in Python
When you want to work with a file, the first thing to do is to open it. This is done by invoking the open() built-in function. open() has a single required argument that is the path to the file. open() has a single return, the file object:
After you open a file, the next thing to learn is how to close it.
Warning: You should always make sure that an open file is properly closed. To learn why, check out the Why Is It Important to Close Files in Python? tutorial.
It’s important to remember that it’s your responsibility to close the file. In most cases, upon termination of an application or script, a file will be closed eventually. However, there is no guarantee when exactly that will happen. This can lead to unwanted behavior including resource leaks. It’s also a best practice within Python (Pythonic) to make sure that your code behaves in a way that is well defined and reduces any unwanted behavior.
When you’re manipulating a file, there are two ways that you can use to ensure that a file is closed properly, even when encountering an error. The first way to close a file is to use the try-finally block:
If you’re unfamiliar with what the try-finally block is, check out Python Exceptions: An Introduction.
The second way to close a file is to use the with statement:
The with statement automatically takes care of closing the file once it leaves the with block, even in cases of error. I highly recommend that you use the with statement as much as possible, as it allows for cleaner code and makes handling any unexpected errors easier for you.
Most likely, you’ll also want to use the second positional argument, mode . This argument is a string that contains multiple characters to represent how you want to open the file. The default and most common is ‘r’ , which represents opening the file in read-only mode as a text file:
Other options for modes are fully documented online, but the most commonly used ones are the following:
| Character | Meaning |
|---|---|
| ‘r’ | Open for reading (default) |
| ‘w’ | Open for writing, truncating (overwriting) the file first |
| ‘rb’ or ‘wb’ | Open in binary mode (read/write using byte data) |
Let’s go back and talk a little about file objects. A file object is:
“an object exposing a file-oriented API (with methods such as read() or write() ) to an underlying resource.” (Source)
There are three different categories of file objects:
- Text files
- Buffered binary files
- Raw binary files
Each of these file types are defined in the io module. Here’s a quick rundown of how everything lines up.
Text File Types
A text file is the most common file that you’ll encounter. Here are some examples of how these files are opened:
With these types of files, open() will return a TextIOWrapper file object:
This is the default file object returned by open() .
Buffered Binary File Types
A buffered binary file type is used for reading and writing binary files. Here are some examples of how these files are opened:
With these types of files, open() will return either a BufferedReader or BufferedWriter file object:
Raw File Types
A raw file type is:
“generally used as a low-level building-block for binary and text streams.” (Source)
It is therefore not typically used.
Here’s an example of how these files are opened:
With these types of files, open() will return a FileIO file object:
Reading and Writing Opened Files
Once you’ve opened up a file, you’ll want to read or write to the file. First off, let’s cover reading a file. There are multiple methods that can be called on a file object to help you out:
| Method | What It Does |
|---|---|
| .read(size=-1) | This reads from the file based on the number of size bytes. If no argument is passed or None or -1 is passed, then the entire file is read. |
| .readline(size=-1) | This reads at most size number of characters from the line. This continues to the end of the line and then wraps back around. If no argument is passed or None or -1 is passed, then the entire line (or rest of the line) is read. |
| .readlines() | This reads the remaining lines from the file object and returns them as a list. |
Using the same dog_breeds.txt file you used above, let’s go through some examples of how to use these methods. Here’s an example of how to open and read the entire file using .read() :
Here’s an example of how to read 5 bytes of a line each time using the Python .readline() method:
Here’s an example of how to read the entire file as a list using the Python .readlines() method:
The above example can also be done by using list() to create a list out of the file object:
Iterating Over Each Line in the File
A common thing to do while reading a file is to iterate over each line. Here’s an example of how to use the Python .readline() method to perform that iteration:
Another way you could iterate over each line in the file is to use the Python .readlines() method of the file object. Remember, .readlines() returns a list where each element in the list represents a line in the file:
However, the above examples can be further simplified by iterating over the file object itself:
This final approach is more Pythonic and can be quicker and more memory efficient. Therefore, it is suggested you use this instead.
Note: Some of the above examples contain print(‘some text’, end=») . The end=» is to prevent Python from adding an additional newline to the text that is being printed and only print what is being read from the file.
Now let’s dive into writing files. As with reading files, file objects have multiple methods that are useful for writing to a file:
| Method | What It Does |
|---|---|
| .write(string) | This writes the string to the file. |
| .writelines(seq) | This writes the sequence to the file. No line endings are appended to each sequence item. It’s up to you to add the appropriate line ending(s). |
Here’s a quick example of using .write() and .writelines() :
Working With Bytes
Sometimes, you may need to work with files using byte strings. This is done by adding the ‘b’ character to the mode argument. All of the same methods for the file object apply. However, each of the methods expect and return a bytes object instead:
Opening a text file using the b flag isn’t that interesting. Let’s say we have this cute picture of a Jack Russell Terrier ( jack_russell.png ):
Image: CC BY 3.0 (https://creativecommons.org/licenses/by/3.0)], from Wikimedia Commons
You can actually open that file in Python and examine the contents! Since the .png file format is well defined, the header of the file is 8 bytes broken up like this:
| Value | Interpretation |
|---|---|
| 0x89 | A “magic” number to indicate that this is the start of a PNG |
| 0x50 0x4E 0x47 | PNG in ASCII |
| 0x0D 0x0A | A DOS style line ending \r\n |
| 0x1A | A DOS style EOF character |
| 0x0A | A Unix style line ending \n |
Sure enough, when you open the file and read these bytes individually, you can see that this is indeed a .png header file:
A Full Example: dos2unix.py
Let’s bring this whole thing home and look at a full example of how to read and write to a file. The following is a dos2unix like tool that will convert a file that contains line endings of \r\n to \n .
This tool is broken up into three major sections. The first is str2unix() , which converts a string from \r\n line endings to \n . The second is dos2unix() , which converts a string that contains \r\n characters into \n . dos2unix() calls str2unix() internally. Finally, there’s the __main__ block, which is called only when the file is executed as a script. Think of it as the main function found in other programming languages.
Tips and Tricks
Now that you’ve mastered the basics of reading and writing files, here are some tips and tricks to help you grow your skills.
__file__
The __file__ attribute is a special attribute of modules, similar to __name__ . It is:
“the pathname of the file from which the module was loaded, if it was loaded from a file.” (Source
Note: To re-iterate, __file__ returns the path relative to where the initial Python script was called. If you need the full system path, you can use os.getcwd() to get the current working directory of your executing code.
Here’s a real world example. In one of my past jobs, I did multiple tests for a hardware device. Each test was written using a Python script with the test script file name used as a title. These scripts would then be executed and could print their status using the __file__ special attribute. Here’s an example folder structure:
Running main.py produces the following:
I was able to run and get the status of all my tests dynamically through use of the __file__ special attribute.
Appending to a File
Sometimes, you may want to append to a file or start writing at the end of an already populated file. This is easily done by using the ‘a’ character for the mode argument:
When you examine dog_breeds.txt again, you’ll see that the beginning of the file is unchanged and Beagle is now added to the end of the file:
Working With Two Files at the Same Time
There are times when you may want to read a file and write to another file at the same time. If you use the example that was shown when you were learning how to write to a file, it can actually be combined into the following:
Creating Your Own Context Manager
There may come a time when you’ll need finer control of the file object by placing it inside a custom class. When you do this, using the with statement can no longer be used unless you add a few magic methods: __enter__ and __exit__ . By adding these, you’ll have created what’s called a context manager.
__enter__() is invoked when calling the with statement. __exit__() is called upon exiting from the with statement block.
Here’s a template that you can use to make your custom class:
Now that you’ve got your custom class that is now a context manager, you can use it similarly to the open() built-in:
Here’s a good example. Remember the cute Jack Russell image we had? Perhaps you want to open other .png files but don’t want to parse the header file each time. Here’s an example of how to do this. This example also uses custom iterators. If you’re not familiar with them, check out Python Iterators:
You can now open .png files and properly parse them using your custom context manager:
Don’t Re-Invent the Snake
There are common situations that you may encounter while working with files. Most of these cases can be handled using other modules. Two common file types you may need to work with are .csv and .json . Real Python has already put together some great articles on how to handle these:
Additionally, there are built-in libraries out there that you can use to help you:
-
: read and write WAV files (audio) : read and write AIFF and AIFC files (audio) : read and write Sun AU files : read and write tar archive files : work with ZIP archives : easily create and parse configuration files : create or read XML based files : read and write Microsoft Installer files : generate and parse Mac OS X .plist files
There are plenty more out there. Additionally there are even more third party tools available on PyPI. Some popular ones are the following:
-
: PDF toolkit : read and write Excel files : image reading and manipulation
You’re a File Wizard Harry!
You did it! You now know how to work with files with Python, including some advanced techniques. Working with files in Python should now be easier than ever and is a rewarding feeling when you start doing it.
In this tutorial you’ve learned:
- What a file is
- How to open and close files properly
- How to read and write files
- Some advanced techniques when working with files
- Some libraries to work with common file types
If you have any questions, hit us up in the comments.
Take the Quiz: Test your knowledge with our interactive “Reading and Writing Files in Python” quiz. Upon completion you will receive a score so you can track your learning progress over time:
Watch Now This tutorial has a related video course created by the Real Python team. Watch it together with the written tutorial to deepen your understanding: Reading and Writing Files in Python
Get a short & sweet Python Trick delivered to your inbox every couple of days. No spam ever. Unsubscribe any time. Curated by the Real Python team.

About James Mertz
James is a passionate Python developer at NASA's Jet Propulsion Lab who also writes on the side for Real Python.
Each tutorial at Real Python is created by a team of developers so that it meets our high quality standards. The team members who worked on this tutorial are:


Master Real-World Python Skills With Unlimited Access to Real Python
Join us and get access to thousands of tutorials, hands-on video courses, and a community of expert Pythonistas:
Master Real-World Python Skills
With Unlimited Access to Real Python
Join us and get access to thousands of tutorials, hands-on video courses, and a community of expert Pythonistas:
What Do You Think?
What’s your #1 takeaway or favorite thing you learned? How are you going to put your newfound skills to use? Leave a comment below and let us know.
Commenting Tips: The most useful comments are those written with the goal of learning from or helping out other students. Get tips for asking good questions and get answers to common questions in our support portal. Looking for a real-time conversation? Visit the Real Python Community Chat or join the next “Office Hours” Live Q&A Session. Happy Pythoning!