Write String to File Python: Safe Simple Method
The safest simple way to write a string to a file in Python is to use the with statement together with the built-in open() function in write mode ('w') and call .write() on the file object. This guarantees the file is properly closed even if an error occurs, and it is the method recommended in Python’s official documentation.
Why the with Statement Matters
When you open a file in Python, the operating system gives your program a file descriptor—a limited resource. If you forget to close the file, the descriptor stays occupied until the program ends, which can cause problems in long-running scripts. The with statement (a context manager) automatically calls close() on the file object when the block exits, whether it exits normally or because of an exception. This is not just a style preference; it prevents resource leaks and ensures your data is flushed from the buffer to disk.
Here is the canonical example:
with open('example.txt', 'w') as f:
f.write('Hello, world!')
If example.txt already exists, this will overwrite it. If it does not exist, Python will create it. The file is opened in text mode by default, which is fine for strings. On Windows, text mode automatically translates \n to \r\n in the file, which is usually what you want for plain text files.
Choosing the Right Mode
The mode string you pass to open() determines whether you write, append, or read. For writing a string, the two most common are:
'w'— write mode. Truncates the file to zero length if it exists, then writes your string. Use this when you want to replace the entire file content.'a'— append mode. Keeps existing content and writes your string at the end. Use this when you want to add to a log file or accumulate data.
There is also 'x' (exclusive creation) which fails if the file already exists—useful when you want to avoid overwriting by accident. For example:
with open('new_file.txt', 'x') as f:
f.write('Brand new file')
If new_file.txt already exists, Python raises a FileExistsError and your original file is untouched.
Encoding: The Hidden Pitfall
Text files are stored as bytes, and the mapping between characters and bytes is defined by an encoding. Python’s open() uses a platform-dependent default encoding (often UTF-8 on Linux and macOS, but historically cp1252 on Windows). If you write a string with characters outside that encoding’s range (like emoji or accented letters) and later read the file with a different encoding, you may get garbled text or a UnicodeEncodeError.
To make your code portable, always specify the encoding explicitly:
with open('example.txt', 'w', encoding='utf-8') as f:
f.write('Café ☕')
UTF-8 is the de facto standard for text files on the web and in most modern applications. It supports every Unicode character, so it is a safe default. If you need to read the file back later, use the same encoding.
Write vs. Print: What’s the Difference?
Many beginners wonder whether they should use f.write() or print() to save text to a file. Both work, but they behave differently:
f.write(string)writes exactly what you give it—no extra newline, no spaces.print(string, file=f)adds a newline at the end (unless you passend='') and can take multiple arguments separated by spaces.
If you want to write a single string with no trailing newline, use write(). If you want to write several lines with automatic newlines, you can use print() with the file parameter:
with open('lines.txt', 'w', encoding='utf-8') as f:
print('First line', file=f)
print('Second line', file=f)
Both methods are safe as long as you use the with block.
Common Mistakes and How to Avoid Them
Even with the simple with method, there are a few pitfalls that trip up developers:
- Forgetting the mode. If you call
open('file.txt')without a mode, it defaults to read mode ('r'), andwrite()will raiseio.UnsupportedOperation. Always include'w','a', or'x'. - Not specifying encoding. As mentioned, this can cause errors or data corruption across platforms. Always add
encoding='utf-8'. - Using
open()withoutwithand forgetting to close. This is the classic resource leak. If you must useopen()withoutwith, wrap it in atry/finallyblock, but thewithstatement is simpler and safer. - Assuming
write()adds a newline. It does not. If you need a newline, include\nin the string or useprint(). - Writing to a file in a directory that doesn’t exist.
open()will not create intermediate directories. If you need to write to./data/output.txtand./datadoesn’t exist, you must create it first withos.makedirs().
When to Use Pathlib (Modern Alternative)
Python 3.4 introduced the pathlib module, which offers an object-oriented way to handle filesystem paths. Its Path.write_text() method is a one-liner that does exactly what the with block does, but with less boilerplate:
from pathlib import Path
Path('example.txt').write_text('Hello, world!', encoding='utf-8')
This method opens the file, writes the string, and closes it automatically. It also handles the encoding parameter. For simple cases, this is arguably even simpler than the with block. However, it does not give you the option to append (use Path.open('a') for that) or to write in binary mode. For most text-writing tasks, Path.write_text() is a clean, safe choice.
Handling Large Strings and Performance
If you are writing a very large string (hundreds of megabytes), the write() method still works, but you may want to consider writing in chunks to avoid holding the entire string in memory. For example, if you generate a string line by line, you can write each line as you go:
with open('big.txt', 'w', encoding='utf-8') as f:
for i in range(1000000):
f.write(f'Line {i}\n')
This is memory-efficient because you never build the entire file content in memory. For most applications, however, writing a single string is perfectly fine.
Frequently Asked Questions
What is the difference between write() and writelines()?
write() takes a single string and writes it as-is. writelines() takes an iterable of strings (like a list) and writes each one without adding newlines between them. If you have a list of lines, you can use f.writelines(lines), but you must include the \n at the end of each line yourself.
How do I write a string to a file without overwriting existing content?
Use append mode: open('file.txt', 'a'). This will add your string to the end of the file. If the file doesn’t exist, it will be created. This is useful for logs or accumulating data across runs.
Why do I get a UnicodeEncodeError when writing a string?
This happens when the encoding you are using (or the default) cannot represent a character in your string. For example, writing ‘é’ with encoding='ascii' will fail. The fix is to use an encoding that supports all characters, such as utf-8. Always specify encoding='utf-8' when opening the file.
Is it safe to use open() without with?
Technically yes, but only if you remember to call f.close() in all cases, including when an exception occurs. The with statement handles this automatically and is the recommended practice. If you see code that calls open() and never closes, it’s a bug waiting to happen.
Can I write to a file in binary mode?
Yes, use 'wb' as the mode. In binary mode, you must write bytes, not strings. For example, f.write(b'hello'). This is useful for images, compressed files, or any non-text data. For strings, stick to text mode with an encoding.
What if I want to write to a file in a different directory?
Provide the full path or a relative path in the open() call. For example, open('data/output.txt', 'w') writes to the data folder inside the current working directory. If the folder doesn’t exist, you’ll get a FileNotFoundError. You can create it with os.makedirs('data', exist_ok=True) before opening the file.
Related
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.