Reading input and working with files — the basics
How a Python program actually gets data from a person typing, or from a file on disk — and the one habit (closing what you open) that prevents a real, common class of bug.
3 min read
input(): pausing to ask the user for text
name = input("What's your name? ")
print(f"Hello, {name}!")input(prompt) displays prompt, pauses the program until the user types something and presses Enter, and returns whatever they typed — always as a str, regardless of what it looks like. Asking for a number needs an explicit conversion, exactly like converting any other string:
age_text = input("How old are you? ")
age = int(age_text) # convert the text to an actual number
print(f"In 10 years you'll be {age + 10}")Skipping the conversion is a very common early bug — age + 10 on a string raises a TypeError, not a calculation, because age is still text until it's explicitly converted.
Opening a file: the basic shape
file = open("notes.txt", "r") # "r" = read mode
content = file.read()
print(content)
file.close() # release the file — don't forget thisopen(path, mode) returns a file object connected to the file on disk. "r" (read) is the default mode; "w" (write) creates a new file or completely overwrites an existing one; "a" (append) adds to the end of an existing file without erasing what's already there. Reading, writing, and appending all require the file to eventually be closed — leaving it open unnecessarily holds a system resource (a file handle) that should be released once you're done, and on some systems, writes aren't fully saved to disk until the file is closed.
The better way: with, which closes the file automatically
with open("notes.txt", "r") as file:
content = file.read()
print(content)
# the file is already closed here, automatically — even if read() had raised an errorwith open(...) as file: is a context manager (covered in depth in its own lesson, once you're comfortable with functions and classes) — it guarantees the file gets closed when the block ends, whether it finished normally or an error interrupted it partway through. This is the standard, idiomatic way to work with files in Python; manually calling .close() is easy to forget, especially once error handling is involved, and forgetting it is a real, common source of bugs (a program that opens many files without closing them can eventually run out of available file handles).
Reading a file line by line
with open("notes.txt", "r") as file:
for line in file:
print(line.strip()) # .strip() removes the trailing newline characterA file object is itself iterable — looping over it with for line in file: yields one line at a time, which is the standard way to process a large file without loading the entire thing into memory at once (the same "process one item at a time instead of building the whole thing in memory first" idea the generators lesson covers, applied here to file reading specifically). .strip() removes whitespace from both ends of a string, most commonly used here to remove the trailing \n (newline character) that .read()/iteration includes at the end of each line.
Writing to a file
with open("output.txt", "w") as file:
file.write("First line\n")
file.write("Second line\n").write(text) writes the given text to the file exactly as given — unlike print(), it doesn't automatically add a newline at the end, so \n has to be included explicitly wherever a line break is actually wanted. Opening in "w" mode and writing to a file that already exists overwrites its entire previous contents — a common early mistake is opening in "w" mode expecting to add to an existing file, which instead erases it first; "a" (append) mode is what actually adds to the end without erasing anything.
Further reading
Check your understanding
A quick comprehension check — not tracked, not graded, just for you.
1. What type does `input("Age: ")` always return, regardless of what the user types?
2. What happens if you open an existing file in `"w"` mode?
3. Why is `with open(path) as f:` preferred over calling open() and close() manually?
4. Why does `for line in file:` avoid loading a large file's entire content into memory at once?