What type are file objects in Python?

Question:

How can I use isinstance to determine the ‘type’ of a file object, such as in the expression:

>>> open(file)
Asked By: Aleeee

||

Answers:

In Python 3.x, normal file objects are of type io.TextIOWrapper:

>>> type(open('file.txt'))
<class '_io.TextIOWrapper'>

>>> from io import TextIOWrapper
>>> isinstance(open('file.txt'), TextIOWrapper)
True

In Python 2.x, all file objects are of type file:

>>> type(open('file.txt'))
<type 'file'>

>>> isinstance(open('file.txt'), file)
True
Answered By: user2555451

Its type is file. You can tell by the output of type(open("file","w"))

Answered By: Nick Retallack

As stated in the documentation for open:

Open a file, returning an object of the file type described in section File Objects.

Thus, open returns a file, and you should use isinstance(foo, file)

Answered By: jwodder

One can pick their preference from the IO class hierarchy. This answer builds upon the previous answer by user2555451 and its comments. The one-line summary is at the end of the answer.

For text files, io.TextIOBase can be acceptable:

>>> import io

>>> type(f := open('/tmp/foo', 'w'))
<class '_io.TextIOWrapper'>
>>> isinstance(f, io.TextIOBase)
True

>>> f.__class__.__bases__
(<class '_io._TextIOBase'>,)
>>> f.__class__.__mro__
(<class '_io.TextIOWrapper'>, <class '_io._TextIOBase'>, <class '_io._IOBase'>, <class 'object'>)

For text files, avoid io.TextIOWrapper because it does not also work for io.StringIO:

>>> isinstance(io.StringIO('foo'), io.TextIOWrapper)
False
>>> isinstance(io.StringIO('foo'), io.TextIOBase)
True

For binary files, io.BufferedIOBase can be acceptable:

>>> import io

>>> type(f := open('/tmp/foo', 'wb'))
<class '_io.BufferedWriter'>
>>> isinstance(f, io.BufferedIOBase)
True

>>> f.__class__.__bases__
(<class '_io._BufferedIOBase'>,)
>>> f.__class__.__mro__
(<class '_io.BufferedWriter'>, <class '_io._BufferedIOBase'>, <class '_io._IOBase'>, <class 'object'>)

For binary files, avoid io.BufferedReader or io.BufferedWriter because they do not also work for io.BytesIO:

>>> isinstance(io.BytesIO(b'foo'), io.BufferedReader)
False
>>> isinstance(io.BytesIO(b'foo'), io.BufferedWriter)
False
>>> isinstance(io.BytesIO(b'foo'), io.BufferedIOBase)
True

To support both text and binary files, io.IOBase is acceptable:

>>> import io

>>> isinstance(open('/tmp/foo', 'w'), io.IOBase)
True
>>> isinstance(open('/tmp/foo', 'wb'), io.IOBase)
True

In summary, I would typically pick io.TextIOBase for text files, io.BufferedIOBase for binary files, and io.IOBase for nonspecific files.

Answered By: Asclepius