---
title: Reading and writing files
description: To read/write to a file in Python, you will want to use the with statement, which will close the file for you after you are done, managing the available resources for you.
---
## The file Reading/Writing process
To read/write to a file in Python, you will want to use the `with`
statement, which will close the file for you after you are done, managing the available resources for you.
## Opening and reading files
The `open` function opens a file and return a corresponding file object.
```python
>>> with open('C:\\Users\\your_home_folder\\hi.txt') as hello_file:
... hello_content = hello_file.read()
...
>>> hello_content
'Hello World!'
```
Alternatively, you can use the _readlines()_ method to get a list of string values from the file, one string for each line of text:
```python
>>> with open('sonnet29.txt') as sonnet_file:
... content = sonnet_file.readlines()
...
>>> content
# [When, in disgrace with fortune and men's eyes,\n',
# ' I all alone beweep my outcast state,\n',
# And trouble deaf heaven with my bootless cries,\n', And
# look upon myself and curse my fate,']
```
You can also iterate through the file line by line:
```python
>>> with open('sonnet29.txt') as sonnet_file:
... for line in sonnet_file:
... print(line, end='')
...
# When, in disgrace with fortune and men's eyes,
# I all alone beweep my outcast state,
# And trouble deaf heaven with my bootless cries,
# And look upon myself and curse my fate,
```
## Writing/Appending to files
```python
>>> with open('bacon.txt', 'w') as bacon_file:
... bacon_file.write('Hello world!\n')
...
>>> with open('bacon.txt', 'a') as bacon_file:
... bacon_file.write('Bacon is not a vegetable.')
...
# Notice that `r` is read mode which is default mode if we omit the argument
>>> with open('bacon.txt', 'r') as bacon_file:
... content = bacon_file.read()
...
>>> print(content)
# Hello world!
# Bacon is not a vegetable.
```
## The with statement
A context manager is an object that is notified when a context (a block of code) starts and ends. You commonly use one with the `with` statement. It takes care of the notifying. For example, file objects are context managers. When a context ends, the file object is closed automatically:
```python
>>> with open(filename) as f:
... file_contents = f.read()
...
>>> # the f object has automatically been closed.
```
Exiting a script without properly closing files/connections is a bad idea, that may cause data loss or other problems. By using a context manager, you can ensure that precautions are always taken to prevent damage or loss in this way.
## Linux and Windows Paths
On Windows, paths are written using backslashes (`\`) as the separator between folder names. On Unix based operating system such as macOS, Linux, and BSDs, the forward slash (`/`) is used as the path separator. Fortunately, Python provides easy ways to handle this. We will showcase
how to deal with both, `os.path.join`.
Using `os.path.join` on Windows:
```python
>>> import os
>>> os.path.join('usr', 'bin', 'spam')
# 'usr\\bin\\spam'
```
Notice the path separator is different between Windows and Unix based operating system, that's why you want to use the above methods instead of adding strings together to join paths together. Joining paths is helpful if you need to create different file paths under the same directory.
Using `os.path.join` on Windows:
```python
>>> my_files = ['accounts.txt', 'details.csv', 'invite.docx']
>>> for filename in my_files:
... print(os.path.join('C:\\Users\\asweigart', filename))
...
# C:\Users\asweigart\accounts.txt
# C:\Users\asweigart\details.csv
# C:\Users\asweigart\invite.docx
```
## Absolute vs. Relative paths
There are two ways to specify a file path.
- An **absolute path**, which always begins with the root folder
- A **relative path**, which is relative to the program’s current working directory
There are also the dot (`.`) and dot-dot (`..`) folders. These are not real folders, but special names that can be used in a path. A single period (“dot”) for a folder name is shorthand for “this directory.” Two periods (“dot-dot”) means “the parent folder.”
## JSON
JSON stands for JavaScript Object Notation and is a lightweight format for storing and transporting data. Json is often used to load or store `list` and `dictionary` in Python.
```python
>>> import json
>>> with open("filename.json", "r") as f:
... content = json.load(f)
```
Write a JSON file with:
```python
>>> import json
>>> content = {"name": "Joe", "age": 20}
>>> with open("filename.json", "w") as f:
... json.dump(content, f, indent=2)
```
## Basic exception handling
### `ZeroDivisionError`
You can't divide by zero, that is a mathematical true, and if you try to do it in Python, the interpreter will raise the built-in exception `ZeroDivisionError`:
```python
>>> def divide(dividend , divisor):
... print(dividend / divisor)
...
>>> divide(dividend=10, divisor=5)
# 2.0
>>> divide(dividend=10, divisor=0)
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# ZeroDivisionError: division by zero
```
Let's say we don't want our program to stop its execution or show the user an output he will not understand. Say we want to print a useful and clear message, then we need to **_handle_** the exception with the `try` and `except` keywords:
```python
>>> def divide(dividend , divisor):
... try:
... print(dividend / divisor)
... except ZeroDivisionError:
... print('You can not divide by 0')
...
>>> divide(dividend=10, divisor=5)
# 2.0
>>> divide(dividend=10, divisor=0)
# You can not divide by 0
```
### `FileNotFoundError` Exception
One common issue when working with files is handling missing files. The file you’re looking for might be in a different location, the filename may be misspelled, or the file may not exist at all. In the example, the code in the `try` block produces a `FileNotFoundError`, so Python looks for an `except` block that matches that error. Python then runs the code in that block, and the result is a friendly error message instead of a traceback.
```python
filename = 'alice.txt'
try:
with open(filename) as f:
contents = f.read()
except FileNotFoundError:
print(f"Sorry, the file {filename} does not exist.")
```
### `ValueError` Exception
`ValueError` in Python is raised when a user gives an invalid value to a function but is of a valid argument. It usually occurs in mathematical operations that will require a certain kind of value, even when the value is the correct argument. For instance, the following code will raise a `ValueError`
```python
int("nsysu")
```
The following code shows that we were able to check for the `ValueError` in our code using the `try` and `except` blocks.
```python
import math
try:
print(math.sqrt(-1))
except ValueError:
print('You can not get take the square root of a negative number ')
```
## Final code in exception handling
Any code that depends on the `try` block executing successfully goes into the `else` block. In addition, the `finally` clause is guaranteed to execute, regardless of whether its `try` suite executes successfully or an exception occurs.
```python
>>> def divide(dividend , divisor):
... try:
... print(dividend / divisor)
... except ZeroDivisionError:
... print('You can not divide by 0')
... else:
... print('Try execution sucessfully')
... finally:
... print('Execution finished')
...
>>> divide(dividend=10, divisor=5)
# 2.0
# Try execution sucessfully
# Execution finished
>>> divide(dividend=10, divisor=0)
# You can not divide by 0
# Execution finished
```
:::info
:bulb: For more different errors, see [here](https://realpython.com/python-traceback/) for more information.
:::