How do you check if an object is an instance of 'file'?

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

Answers (4)

tilnam
tilnam

Reputation: 51

In python3 you could refer to io instead of file and write

import io
isinstance(f, io.IOBase)

Upvotes: 5

jfs
jfs

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

aaronasterling
aaronasterling

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

Doug
Doug

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

Related Questions