Concepts / Opening Files and Getting File Handles

Opening Files and Getting File Handles

Attempting to open a non-existent file raises a FileNotFoundError and prevents the program from obtaining a file handle.

  • Programming
Interactive lab

Try it: Reading and Writing Text Files

How open() returns a file object with a position pointer, how read(), read(n), readline(), readlines() and for line in fh advance it (and return '' at the end), how 'w' and 'a' modes change the file, and why a closed file (after close() or a with block) can no longer be read.

How it works

  1. open(name, 'r') starts the pointer at 0; 'w' empties the file first; 'a' starts at the end.
  2. read() returns everything from the pointer to the end; read(n) at most n characters; readline() up to and including the next \n; each moves the pointer past what it returned.
  3. At the end of the file every read returns '' (an empty string), which is how loops know to stop; for line in fh reads line by line the same way.
  4. write() text waits in a buffer and reaches the file when it is closed (or the program ends); reading a 'w'/'a' file or writing an 'r' file raises io.UnsupportedOperation.
  5. close(), or leaving a with block, closes the file; any further read raises ValueError: I/O operation on closed file.

Default run (10 steps): Ready: notes.txt holds 4 lines (51 characters). Nothing is open yet. … Finished. notes.txt now holds "From: stephen\nSubject: meeting\nFrom: louis\nThanks!\n".

Simplified: The lab's own small Python interpreter runs a fixed, hand-written script (you choose the variant and the values, never the code); nothing is executed as real Python. Every script was run in CPython 3.12 with the same inputs and the lab reproduces its output and error messages. One virtual text file with \n line endings (as on Linux/macOS), positions counted in characters (ASCII only), and a write buffer that is only flushed by close() or the end of the program.

Educational simulation

Loading the simulation…

The Failed Opening

When a program calls open() for a file that is not where the program expects it to be, Python cannot obtain a file handle. Instead, it raises FileNotFoundError. Without error handling, execution stops at the failed call, so statements after it do not run.

What do you think happens?

Suppose the file does not exist. Which statement runs: the statement immediately after open(), or an error-handling statement in an except block?

  • The statement immediately after open()

  • The matching except block, if one exists

  • Both statements

Reveal answer
Answer:

The matching except block, if one exists. Without a matching except block, execution stops and the later statement does not run.

A failed operation inside a try block transfers control to its matching except block. If the failure is not caught, Python stops execution and displays a traceback.

Control Flow Without Handling

python

In this example, the call to open() is the point of failure when missing_notes.txt does not exist. Python does not assign a file handle to file_handle. Because the error is not caught, the print() statement is never reached, and the program terminates with a traceback.

Program startsopen()requested fileFile missingFileNotFoundErrortraceback displayedProgram stopsexecutecheck requested filefile does not existuncaught
What happens next when open() cannot find the requested file and no error handler catches the failure?

Reading the Traceback

A traceback is the error information Python displays when the failure is not handled. It identifies where the failure occurred, shows the code that failed, and names the error type as FileNotFoundError. The error means that Python looked for the requested file but did not find it where the program said it would be.

  • The opening part indicates that a traceback is being reported.
  • The location information identifies the file and line where the failure occurred.
  • The code information shows the statement that failed.
  • The final error information names FileNotFoundError and gives details about the missing file.
Tracebackfailure reportFile and linefailure locationopen() callfailed codeFileNotFoundErrorerror typeProgram stopsuncaught failureshowsidentifiesraisesuncaught
How does the traceback show where the failure occurred, what exception was raised, and why normal flow stopped?

Handling the Failure

A try statement marks code that might fail. A matching except statement provides the response when that code raises the specified error. If open() raises FileNotFoundError inside the try block, Python jumps to the matching except block. After the except block finishes, execution continues normally.

python
Output
The file was not found
The program continues

The first print() inside the try block is skipped because the failure occurs before it. Control moves directly to except FileNotFoundError. The handler prints its message, and then the final print() runs because the error has been handled rather than left uncaught.

try blockrun open()open()requested fileFile existsNormal statementscontinue try flowFollowing statementsprogram continuesFileNotFoundErrorexcept blockhandle failureentercheckyesnomatching errorfinish tryhandler finishes
How does control flow branch from the try block to the except block when opening the file fails?

Handle or No Handle

The important state change is whether the program obtains a file handle. When the requested file is available, open() can provide a handle for the program to use. When the file is missing, FileNotFoundError occurs instead, so no file handle is obtained from that call.

Requested filefile existsFile handleobtainedRequested filefile does not existFileNotFoundErrorraisedFile handlenot obtainedopen() succeedsopen() failsprevents acquisition
What is available after open() succeeds, and what is missing when FileNotFoundError prevents the opening?
Worked example

Following a Missing-File Attempt

Predict the execution order when open() cannot find the requested file.

  1. 1
    Step 1

    Python enters the try block and attempts to call open().

  2. 2
    Step 2

    The requested file is not found, so open() raises FileNotFoundError instead of producing a file handle.

  3. 3
    Step 3

    Python skips the remaining statements in the try block and enters the matching except block.

  4. 4
    Step 4

    After the except block completes, Python continues with statements that follow the try and except structure.

Result

The error-handling response runs, the remaining statements in the failed try block do not run, and later program execution can continue.

Common Mistakes

  • Common mistake

    Assuming that every open() call produces a file handle.

    What it looks like
    file_handle = open("missing_notes.txt")
    Why it fails

    If the requested file does not exist, open() raises FileNotFoundError and no handle is obtained.

    Do this instead

    Consider that opening can fail, and place the call in a try block when the failure should be handled.

  • Common mistake

    Expecting statements after an uncaught open() failure to run.

    What it looks like
    open("missing_notes.txt")
    print("Finished")
    Why it fails

    An uncaught FileNotFoundError stops execution immediately.

    Do this instead

    Use a matching except FileNotFoundError block if the program should respond and continue.

  • Common mistake

    Treating the traceback as a syntax error.

    What it looks like

    The code is syntactically valid, but the requested file is missing while the program runs.

    Why it fails

    FileNotFoundError is a runtime error caused by the unavailable file, not by invalid Python syntax.

    Do this instead

    Read the traceback for the failed line and the error type, then decide whether to handle the missing file.

  • Common mistake

    Putting the file-opening call outside the try block.

    What it looks like
    file_handle = open("missing_notes.txt")
    try:
        print("Handling the problem")
    except FileNotFoundError:
        print("Not found")
    Why it fails

    The failure occurs before Python enters the try block, so that except block cannot handle this call.

    Do this instead

    Put the operation that might raise FileNotFoundError inside the try block.

Practice the Branch

EASY

A program tries to open a file that is not present. It has a try block containing open(), an except FileNotFoundError block that prints a message, and a final print() statement after the handler. Predict which messages appear and explain why.

Hints
  • The failed open() prevents later statements in the same try block from running.
  • A matching except block receives control when FileNotFoundError is raised.
  • Execution can continue after the except block finishes.
Best practice

Treat FileNotFoundError as a normal possibility when a program depends on a file. Files can be deleted, moved, renamed, or never created, so a robust program should decide how to respond instead of allowing an unexpected traceback to terminate execution.

Key Takeaways

  1. 1
    Calling open() for a missing file raises FileNotFoundError and does not provide a file handle.
  2. 2
    Without handling, the error stops execution and displays a traceback.
  3. 3
    The traceback identifies the failure location, the failed code, and the FileNotFoundError type.
  4. 4
    A try block contains the operation that might fail, while a matching except block defines the response.
  5. 5
    After the except block completes, execution can continue with later statements.

At a glance

  • A missing file prevents open() from obtaining a file handle and raises FileNotFoundError.
  • An uncaught FileNotFoundError stops the program at the failed open() call.
  • A traceback explains where the failure occurred and identifies the error type.
  • try and except redirect control to an error handler and allow execution to continue afterward.

Related concepts

More concepts starting with O