> For the complete documentation index, see [llms.txt](https://ricardomol.gitbook.io/notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ricardomol.gitbook.io/notes/backend/python/open-function.md).

# Open function

## `open` Function

Opens a file.

There are **3 errors** in the following code:

```python
f = open('photo.jpg', 'r+')
jpgdata = f.read()
f.close()
```

**The return value from `open` is a file handle**, given out from the operating system to your Python application. You will want to return this file handle once you’re finished with the file, if only so that your application won’t reach the limit of the number of open file handles it can have at once.

**Explicitly calling `close` closes the file handle, but only if the read was successful**. If there is any error just after `f = open(...)`, `f.close()` will not be called (depending on the Python interpreter, the file handle may still be returned, but that’s another story).

To ensure that the file gets closed whether an exception occurs or not, **pack it into a `with` statement**:

```python
with open('photo.jpg', 'r+') as f:
    jpgdata = f.read()
```

**The first argument of `open` is the filename**.&#x20;

**The second one (the&#x20;*****mode*****) determines&#x20;*****how*****&#x20;the file gets opened.**

* If you want to read the file, pass in `r`
* If you want to read and write the file, pass in `r+`
* If you want to overwrite the file, pass in `w`
* If you want to append to the file, pass in `a`

The mode can contain one further character; we can open the file in binary (you’ll get a string of bytes) or text mode (a string of characters).

If you open something in text mode (i.e. add a `t`, or nothing apart from `r/r+/w/a`), you must also know which encoding to use. For a computer, all files are just bytes, not characters.

Unfortunately, `open` does not allow explicit encoding specification in Python 2.x. However, the function [io.open](http://docs.python.org/2/library/io.html#io.open) is available in both Python 2.x and 3.x (where it is an alias of `open`), and does the right thing. **You can pass in the encoding with the `encoding` keyword**. If you don’t pass in any encoding, a system – and Python – specific default will be picked. You may be tempted to rely on these defaults, but the defaults are often wrong, or the default encoding cannot actually express all characters in the file (this will happen often on Python 2.x and/or Windows). So go ahead and pick an encoding. **Encoding is the way to instruct computers about how the numbers should be stored as bytes in memory. `utf-8` is a terrific one and is supported by major browsers and programming languages.** When you write a file, you can just pick the encoding to your liking (or the liking of the program that will eventually read your file).

**How do you find out which encoding a file you’re reading was written in? Well, unfortunately, there is no foolproof way to detect the encoding - the same bytes can represent different, but equally valid characters in different encodings. Therefore, you must rely on metadata (for example, in HTTP headers) to know the encoding. Increasingly, formats just define the encoding to be UTF-8.**

## Example

Write a program that reads a file, determines whether it’s JPG (hint: These files start with the bytes `FF D8`), and writes a text file that describe the input file:

```python
import io

with open('photo.jpg', 'rb') as inf:
    jpgdata = inf.read()

if jpgdata.startswith(b'\xff\xd8'):
    text = u'This is a JPEG file (%d bytes long)\n'
else:
    text = u'This is a random file (%d bytes long)\n'

with io.open('summary.txt', 'w', encoding='utf-8') as outf:
    outf.write(text % len(jpgdata))
```
