Writing to a text file is one of the first practical things you will do in Python. Once you know how, you can save program output, log data, store user input, and build tools that remember information between runs.
Python gives you a built-in function called open() for working with files. You do not need to install anything extra. Understanding two things — which mode to use and how to close the file properly — gets you most of the way there.
The open() Function and Write Modes
The open() function takes a filename (and optionally a path) as its first argument, and a mode string as its second. For writing, the two modes you need to know are 'w' and 'a'.
The file is created automatically if it does not exist yet, regardless of whether you use 'w' or 'a' mode. You never need to create the file manually first.
The safest way to open a file in Python is with a context manager — a with statement. It closes the file automatically when the indented block finishes, even if something goes wrong inside the block.
# Open a file for writing using a context manager
with open("notes.txt", "w", encoding="utf-8") as f:
f.write("Hello from Python!")
# The file is closed automatically when the with block ends
The variable f is the file object. You call methods on it — like .write() — to interact with the file. The name f is a convention; you can use any valid variable name.
The comparison table below shows the four most common file modes and what each one does.
- Behavior
- Creates the file if it does not exist. Overwrites all existing content if the file already exists.
- Use when
- You want to write fresh content and do not need anything that was there before.
- Behavior
- Creates the file if it does not exist. Adds new content after any existing content without erasing it.
- Use when
- You want to keep existing data and add more — for example, a running log file.
- Behavior
- Opens an existing file for reading only. Raises a FileNotFoundError if the file does not exist.
- Use when
- You need to read data from a file without modifying it. This is the default mode if you omit the mode argument.
- Behavior
- Creates a new file and raises a FileExistsError if the file already exists.
- Use when
- You want to guarantee you are not overwriting an existing file. Useful when the file should only ever be created once.
Writing Text and Handling Newlines
The .write() method accepts a single string and writes it to the file. It returns the number of characters written, though you typically do not need to use that return value.
.write() does not add a newline at the end of your string automatically. If you call it twice without including \n, both strings will run together on the same line in the file.
# Writing multiple lines — \n creates the line break
with open("shopping.txt", "w", encoding="utf-8") as f:
f.write("Apples\n")
f.write("Bread\n")
f.write("Coffee\n")
# Result in shopping.txt:
# Apples
# Bread
# Coffee
Writing a list of items with a loop is a cleaner approach when you have several lines to write.
items = ["Apples", "Bread", "Coffee", "Eggs"]
with open("shopping.txt", "w", encoding="utf-8") as f:
for item in items:
f.write(item + "\n")
Python also provides a .writelines() method that accepts an iterable of strings and writes each one in sequence. Like .write(), it does not add newlines automatically — you must include them in each string.
lines = ["Line one\n", "Line two\n", "Line three\n"]
with open("output.txt", "w", encoding="utf-8") as f:
f.writelines(lines)
When you write numbers or other non-string data types, convert them to strings first. Python's .write() only accepts strings. Use str() — for example, f.write(str(score) + "\n") — or an f-string: f.write(f"{score}\n"). Also pass encoding="utf-8" to every open() call. Without it, Python falls back to the platform default, which is cp1252 on Windows and will silently mangle any character outside basic ASCII.
Build the correct Python statement that opens "log.txt" in write mode and writes a line to it:
with open("log.txt", "w") as f: followed by f.write("Started.\n"). The mode must be "w" (not "r", which is read-only). The with keyword comes first, then open(, then the filename, then the mode, then the closing paren and as f:. The write call comes after the colon, indented inside the with block.
Appending vs. Overwriting
Every time you open a file with 'w' mode, Python erases everything in it before writing. This is the right choice when you want a clean slate, but it causes data loss if you wanted to keep previous content.
Use 'a' mode whenever you want to preserve what is already in the file.
# First run — creates the file and writes the first entry
with open("events.txt", "a", encoding="utf-8") as f:
f.write("2026-04-05 09:00 — Server started\n")
# Second run — adds a new entry without erasing the first
with open("events.txt", "a", encoding="utf-8") as f:
f.write("2026-04-05 09:15 — User logged in\n")
After both runs, events.txt contains two lines. If you had used 'w' on the second run, only the second line would remain.
According to the official Python documentation, when no mode is specified,open()defaults to'r'— reading text. This is also written as'rt', confirming that text mode is the implicit baseline. — Python Software Foundation, docs.python.org/3/library/functions.html
The code below tries to write a number to a file, but it will raise a TypeError. Find the line with the bug.
f.write(score) to f.write(str(score)). The .write() method only accepts strings. Passing an integer directly raises a TypeError: write() argument must be str, not int. Wrapping with str() converts the number to its string representation before writing.
How to Write to a Text File in Python
The steps below cover the complete process from opening the file through writing multiple lines and appending safely.
-
Open the file in write mode
Use
with open("filename.txt", "w", encoding="utf-8") as f:. Thewithstatement creates a context manager that closes the file automatically. The mode"w"creates the file if it does not exist and erases it if it does. Always includeencoding="utf-8"— without it, Python uses the platform default, which iscp1252on Windows and can cause encoding errors on any non-ASCII text. -
Write your text using .write()
Inside the indented block, call
f.write("your text\n"). Include\nat the end of each string to produce a line break in the file. You can call.write()as many times as you need within the same block. -
Let the context manager close the file
When the
withblock ends (you un-indent), Python flushes any buffered data and closes the file handle. No explicitf.close()call is needed. If you open withoutwith, you must callf.close()yourself. -
Append to an existing file using 'a' mode
Replace
"w"with"a"in theopen()call, keepingencoding="utf-8". Everything you write will be added after the last existing character in the file. Existing content is never erased in append mode. -
Write multiple lines with a loop
Store your data in a list and use a
forloop inside thewithblock. Callf.write(item + "\n")on each iteration. This approach scales cleanly regardless of how many items your list contains.
# Complete example — write a list of scores to a file
scores = [95, 87, 72, 100, 66]
with open("scores.txt", "w", encoding="utf-8") as f:
f.write("Score Report\n")
f.write("============\n")
for i, score in enumerate(scores, start=1):
f.write(f"Student {i}: {score}\n")
# Append a summary line later
with open("scores.txt", "a", encoding="utf-8") as f:
average = sum(scores) / len(scores)
f.write(f"\nAverage: {average:.1f}\n")
Key Takeaways
- Use
open(filename, "w", encoding="utf-8")to create or overwrite a file, andopen(filename, "a", encoding="utf-8")to add to an existing one without erasing it. - Always prefer a
withstatement — it closes the file automatically and prevents data from being lost if an error occurs. - The
.write()method only accepts strings. Convert integers and floats withstr()or use f-strings before passing them to.write(). - Newlines are your responsibility. Add
\nto the end of each string if you want each piece of text to appear on its own line in the file. - Always pass
encoding="utf-8"toopen(). Without it Python uses the OS default, which iscp1252on Windows — a silent cross-platform bug that only surfaces when someone outside Mac/Linux runs your script.
File I/O is one of those skills that shows up constantly once you start writing real programs. With open(), .write(), and a solid understanding of modes, you have everything you need to save data from any Python script.
Frequently Asked Questions
You use Python's built-in open() function with a write mode such as 'w' (write) or 'a' (append), then call the .write() method on the file object it returns.
The 'w' mode creates the file if it does not exist and overwrites all existing content every time it is opened. The 'a' mode also creates the file if needed, but it adds new content to the end of any existing content without erasing it.
Yes. When you open a file with 'w' or 'a' mode, Python creates the file automatically if it does not already exist.
The with statement (context manager) automatically closes the file when the indented block finishes, even if an error occurs. This prevents data loss and resource leaks from unclosed file handles.
Call .write() multiple times inside the with block and include a newline character \n at the end of each string, or pass a list of strings to .writelines(). Using a for loop is also a common and scalable approach.
No. Python's .write() method does not add a newline character automatically. You must include \n explicitly inside each string you write if you want lines to be separated in the file.
Open the file with mode 'a' instead of 'w'. Everything written will be added after the last existing line without touching any previous content.
.write() returns an integer representing the number of characters written to the file. In most everyday use you do not need to capture or check this value.
No. .write() only accepts strings. To write a number, convert it to a string first using str(), for example f.write(str(42)), or use an f-string: f.write(f"{42}\n").
.write() accepts a single string argument and writes it to the file. .writelines() accepts an iterable of strings and writes each one in sequence. Neither method adds newlines automatically — you must include \n in each string yourself.
Yes, always. Without encoding="utf-8", Python uses the OS default — which is cp1252 on Windows. Any character outside basic ASCII (accented letters, currency symbols, anything non-English) will either raise a UnicodeEncodeError or be written incorrectly on Windows machines. Passing encoding="utf-8" explicitly guarantees consistent behaviour regardless of where your script runs.