Open a file.
The mode can be 'r' (default), 'w', 'x' or 'a' for reading,
writing, exclusive creation or appending. The file will be created
if it doesn't exist when opened for writing or appending; it will be
truncated when opened for writing. A FileExistsError will be raised
if it already exists when opened for creating. Opening a file for
creating implies writing so this mode behaves in a similar way to
'w'. Add a '+' to the mode to allow simultaneous reading and
writing.
A custom opener can be used by passing a callable as *opener*.
The underlying file descriptor for the file object is then obtained
by calling opener with (*name*, *flags*). *opener* must return
an open file descriptor (passing os.open as *opener* results in
functionality similar to passing None).