Open and Close Files in Python

Learn how to use Python's open() and close() functions to access files on disk, understand file modes, and build the foundation for every file operation.

5 min read

To open and close files in Python, your program first establishes a connection to the file through the operating system. The built-in open function creates that connection and hands you a file object, a handle that represents your program's access to the file on disk. Every read, write, or append operation you perform flows through this file object, and when you are finished, the close method tears down the connection cleanly so the operating system can reclaim the resources it allocated. This open-close pair is the entry and exit gate for all file handling, and understanding it thoroughly makes every other file operation predictable and safe.

The open function looks simple on the surface: you give it a filename and a mode, and it gives you back a file object. But the details matter. The mode you choose determines what you can do with the file, whether Python creates it if it does not exist, and whether your writes overwrite existing content or add to the end. The encoding you specify for text files determines whether characters outside the ASCII range survive the trip to disk and back. And whether you call close explicitly or rely on the with statement determines whether your program handles file resources responsibly or leaks them over time.

The open() function and its arguments

The open function accepts a required file path, an optional mode string, and several optional keyword arguments that control buffering, encoding, and error handling. In its most common form, you call it with a filename and a mode. The file path tells Python where to find the file on disk, and the mode tells Python what you intend to do with it. If you omit the mode, Python defaults to reading in text mode, which is the safest default since reading cannot destroy data.

pythonpython
file = open("journal.txt", "r")

This line tells Python to open a file named journal.txt for reading in text mode. Python looks for the file in the current working directory, which is the directory where your terminal or code editor ran the script. If the file exists, the open call returns a file object that you can read from. If the file does not exist, it raises a FileNotFoundError, and your program stops unless you handle the error. This immediate feedback is helpful during development because it tells you exactly what went wrong instead of silently producing an empty or corrupted result.

When you want to write to a file, you pass w as the mode. If the file already exists, opening it in write mode erases its contents immediately, before you even call any write methods. If the file does not exist, Python creates it. This truncation behavior is the most common surprise for learners: opening an existing file with write mode wipes it clean, so you must be certain you want to overwrite before using that mode. If you want to add content to the end of a file without touching what is already there, you use append mode, which you will explore in detail in the article on appending data to files in Python.

Exclusive creation mode occupies a useful middle ground. Like write mode, it opens a file for writing, but instead of silently overwriting an existing file, it raises a FileExistsError if the file already exists. This is the right mode when you are generating output files and you want to avoid accidentally clobbering data that you did not intend to replace. Combined with try-except error handling from the error handling section, exclusive creation lets you write programs that refuse to overwrite existing work unless you explicitly tell them to.

pythonpython
try:
    with open("report.txt", "x") as file:
        file.write("Quarterly Report\n")
except FileExistsError:
    print("report.txt already exists. Not overwriting.")

The with statement in this example handles closing automatically, and the encoding parameter has been omitted for brevity here. In production code, you should always pass encoding explicitly when opening text files. Python's default encoding varies by platform: UTF-8 on macOS and Linux, and typically a locale-specific encoding on Windows. Passing encoding="utf-8" makes your intent explicit and your code portable across every operating system that runs Python.

Understanding file modes in detail

The mode string you pass to the open function is a compact language for describing what you intend to do with the file. Each character in the string modifies the behavior, and you combine them to build the exact access pattern your program needs. The most common modes fit on a small reference card, but the combinations can express subtle permissions that are worth understanding before you write code that depends on them.

The base mode characters are r for reading, w for writing with truncation, a for appending, and x for exclusive creation. The default mode when you omit the second argument is r, read-only in text mode. Because reading is the safest operation, this default encourages the right habit: be explicit when you intend to modify a file, and let the default protect you when you are only reading.

Adding a plus character to any base mode adds the complementary operation. For example, r+ opens for both reading and writing without truncating. The w+ mode opens for both reading and writing but still truncates. The a+ mode opens for both reading and appending. These dual-purpose modes are powerful but require care because the file position matters. In r+ mode, your writes start at whatever position the file pointer is currently at, and you are responsible for managing that position correctly.

Adding a b character switches to binary mode: rb, wb, ab, xb, and their plus variants. Binary mode bypasses the text encoding and decoding layer entirely. You read and write bytes objects instead of strings, and Python performs no line-ending translation. This is the mode you use for images, audio, video, compiled code, serialized data, and any format where the concept of a character does not apply. The next article on reading files in Python covers the specific methods you call after opening in each mode.

The cost of forgetting to close

Every file object you create with the open function consumes an operating system resource called a file descriptor. The operating system limits how many file descriptors a single process can hold at once, typically a few hundred to a few thousand depending on the system. In a short script that opens one file, reads it, and exits, you might never notice a leak. In a program that processes hundreds of files in a loop, or a long-running server that opens log files over days or weeks, every unclosed file accumulates until the operating system refuses to grant more and your program crashes.

The close method releases the file descriptor and flushes any buffered writes to disk. After you call close, the file object is no longer usable; calling read or write on a closed file raises a ValueError. This one-way transition makes the file's lifecycle explicit: open, operate, close, done. The pattern is simple enough to write correctly, but easy to get wrong when errors interrupt the flow between open and close. The with statement, which you will learn in detail in the article on using the Python with statement for files, solves this by calling close automatically when the block ends, even if an exception fires halfway through your file operations.

The close method also matters for data integrity when writing. Python buffers writes in memory for efficiency, and the buffer is flushed to the actual disk when you close the file, when the buffer fills up, or when you explicitly call the flush method. If your program crashes after a write but before a close, the data in the buffer is lost. The with statement protects against this by ensuring close runs even when exceptions occur.

Rune AI

Rune AI

Key Insights

  • The open() function takes a file path and a mode string and returns a file object you use to read from or write to the file.
  • File modes like 'r', 'w', 'a', and 'x' control whether you are reading, writing, appending, or creating exclusively.
  • Always call close() when you are done with a file, or use the with statement to close it automatically even when errors occur.
  • Text mode is the default and works with strings; binary mode works with bytes and needs a 'b' in the mode string.
  • Specifying encoding='utf-8' when opening text files prevents silent corruption on systems with different default encodings.
RunePowered by Rune AI

Frequently Asked Questions

What happens if I forget to close a file in Python?

If you forget to call close(), Python will eventually close the file when the file object is garbage collected or when the program exits. However, relying on this is dangerous. Data you wrote might not be flushed to disk, other programs might be blocked from accessing the file, and the operating system limits how many files a process can have open at once. Always close files explicitly, or better, use the with statement which closes them automatically.

What is the default file mode when I open a file?

The default mode is 'r', which opens the file for reading in text mode. If you call open('data.txt') with no mode argument, Python treats it as open('data.txt', 'r'). The file must exist, or Python raises a FileNotFoundError.

Can I open a file that does not exist?

It depends on the mode. Modes 'r' and 'r+' require the file to exist and raise FileNotFoundError if it does not. Modes 'w', 'w+', 'a', 'a+', and 'x' create the file if it does not exist. Mode 'x' is special because it raises FileExistsError if the file already exists, which is useful when you want to ensure you are creating a brand new file.

Conclusion

The open() function and close() method are the entry and exit points for every file interaction in Python. Choose the right mode for your operation, provide an encoding when working with text, and always close your files. Better yet, reach for the with statement in the next articles and let Python manage the close step for you automatically.