Is there a Python 2/3-compatible way of checking whether an object is a file?
I need to check if an object filehandler
is actually a file
object. This code needs to run in both Python 2 and 3. In Python 2 I could do
isinstance(filehandler, file)
However file
is not part of Python 3, so this code raises a NameError
when run with Python 3.
According to this answer, in Python 3 io.IOBase
should be used to check if an object is a file, but Python 2's file
doesn't subclass io.IOBase
, so isinstance(filehandler, io.IOBase)
won't work.
I thought about doing isinstance(filehandler, (io.IOBase, file))
, but that still gives a NameError
when I run it with Python 3.
Is there a way to do this that is compatible with both Python 2.7 and 3?
I found that the most common way of doing this is to check hasattr
in Python 3. So, I added a check that will check the version of Python, and depending on that, it will execute the right function.
import sys
def isFile(f):
return isinstance(f,file) if sys.version_info[0] == 2 else hasattr(f, 'read')
f = open("post.php","r")
print(isFile(f))
print(isFile(10))
Alternatively, you can use a lambda
, but I find it less readable.
isFile = lambda f:isinstance(f,file) if sys.version_info[0] == 2 else hasattr(f, 'read')
This was the workaround I used: at the top of the .py
file, I added:
import sys
if sys.version_info[0] == 3:
from io import IOBase
file = IOBase
So if Python 3 is being used, set file
to be IOBase
. Now isinstance(filehandler, file)
will work correctly in Python 3, and for Python 2 it will work just like it always has.
Of course, this solution is extremely hackish and confusing, since it makes it look like IOBase
is the Python 3 version of file
, which is not the case. But it does solve the problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With