Reputation: 146
It used to be in Python (2.6) that one could ask:
isinstance(f, file)
but in Python 3.0 file
was removed.
What is the proper method for checking to see if a variable is a file now? The What'sNew docs don't mention this...
Upvotes: 3
Views: 6204
Reputation: 51
In python3 you could refer to io instead of file and write
import io
isinstance(f, io.IOBase)
Upvotes: 5
Reputation: 414875
Typically, you don't need to check an object type, you could use duck-typing instead i.e., just call f.read()
directly and allow the possible exceptions to propagate -- it is either a bug in your code or a bug in the caller code e.g., json.load()
raises AttributeError
if you give it an object that has no read
attribute.
If you need to distinguish between several acceptable input types; you could use hasattr/getattr
:
def read(file_or_filename):
readfile = getattr(file_or_filename, 'read', None)
if readfile is not None: # got file
return readfile()
with open(file_or_filename) as file: # got filename
return file.read()
If you want to support a case when file_of_filename
may have read
attribute that is set to None
then you could use try/except
over file_or_filename.read
-- note: no parens, the call is not made -- e.g., ElementTree._get_writer()
.
If you want to check certain guarantees e.g., that only one single system call is made (io.RawIOBase.read(n)
for n > 0) or there are no short writes (io.BufferedIOBase.write()
) or whether read/write methods accept text data (io.TextIOBase
) then you could use isinstance()
function with ABCs defined in io
module e.g., look at how saxutils._gettextwriter()
is implemented.
Upvotes: 1
Reputation: 71064
def read_a_file(f)
try:
contents = f.read()
except AttributeError:
# f is not a file
substitute whatever methods you plan to use for read
. This is optimal if you expect that you will get passed a file like object more than 98% of the time. If you expect that you will be passed a non file like object more often than 2% of the time, then the correct thing to do is:
def read_a_file(f):
if hasattr(f, 'read'):
contents = f.read()
else:
# f is not a file
This is exactly what you would do if you did have access to a file
class to test against. (and FWIW, I too have file
on 2.6) Note that this code works in 3.x as well.
Upvotes: 5
Reputation: 9110
Works for me on python 2.6... Are you in a strange environment where builtins aren't imported by default, or where somebody has done del file
, or something?
Upvotes: -3