Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if object is file-like in Python

Tags:

python

file

File-like objects are objects in Python that behave like a real file, e.g. have a read() and a write method(), but have a different implementation from file. It is realization of the Duck Typing concept.

It is considered a good practice to allow a file-like object everywhere where a file is expected so that e.g. a StringIO or a Socket object can be used instead a real file. So it is bad to perform a check like this:

if not isinstance(fp, file):
   raise something

What is the best way to check if an object (e.g. a parameter of a method) is "file-like"?

like image 697
dmeister Avatar asked Nov 02 '09 13:11

dmeister


People also ask

How to check if variable is file object Python?

In some systems (for example fastai ), path = pathlib. Path("filename") has both read and write attributes but is not a file-like object. It's probably best to use insintance(fp, io. IOBase) as some comments below suggest.

Is Python an object file?

Python file object provides methods and attributes to access and manipulate files. Using file objects, we can read or write any files. Whenever we open a file to perform any operations on it, Python returns a file object. To create a file object in Python use the built-in functions, such as open() and os.

How to check whether an object is a file object in Python?

Two Methods To Check Whether An Object Is A File Object In Python Or Not 1 Compare Object Type.#N#The first method is to determine whether the object type is file or not.But this method does not... 2 Use isinstance Method. More ...

What are file-like objects in Python?

File-like objects are objects in Python that behave like a real file, e.g. have a read () and a write method (), but have a different implementation from file. It is realization of the Duck Typing concept.

How to do a file check in Python 3?

As a side note, you can't do the file check in the same way in Python 3. You'll need something like isinstance (f, io.IOBase) instead. Show activity on this post. It is generally not good practice to have checks like this in your code at all unless you have special requirements.

How to judge whether an object is a file or not?

File manipulation is a common scenario in development, so how to judge whether an object is a file object or not? Here we summarise two methods . 1. Compare Object Type. The first method is to determine whether the object type is file or not.But this method does not apply to sub classes inherited from file.


4 Answers

For 3.1+, one of the following:

isinstance(something, io.TextIOBase)
isinstance(something, io.BufferedIOBase)
isinstance(something, io.RawIOBase)
isinstance(something, io.IOBase)

For 2.x, "file-like object" is too vague a thing to check for, but the documentation for whatever function(s) you're dealing with will hopefully tell you what they actually need; if not, read the code.


As other answers point out, the first thing to ask is what exactly you're checking for. Usually, EAFP is sufficient, and more idiomatic.

The glossary says "file-like object" is a synonym for "file object", which ultimately means it's an instance of one of the three abstract base classes defined in the io module, which are themselves all subclasses of IOBase. So, the way to check is exactly as shown above.

(However, checking IOBase isn't very useful. Can you imagine a case where you need to distinguish an actual file-like read(size) from some one-argument function named read that isn't file-like, without also needing to distinguish between text files and raw binary files? So, really, you almost always want to check, e.g., "is a text file object", not "is a file-like object".)


For 2.x, while the io module has existed since 2.6+, built-in file objects are not instances of io classes, neither are any of the file-like objects in the stdlib, and neither are most third-party file-like objects you're likely to encounter. There was no official definition of what "file-like object" means; it's just "something like a builtin file object", and different functions mean different things by "like". Such functions should document what they mean; if they don't, you have to look at the code.

However, the most common meanings are "has read(size)", "has read()", or "is an iterable of strings", but some old libraries may expect readline instead of one of those, some libraries like to close() files you give them, some will expect that if fileno is present then other functionality is available, etc. And similarly for write(buf) (although there are a lot fewer options in that direction).

like image 155
abarnert Avatar answered Oct 20 '22 23:10

abarnert


As others have said you should generally avoid such checks. One exception is when the object might legitimately be different types and you want different behaviour depending on the type. The EAFP method doesn't always work here as an object could look like more than one type of duck!

For example an initialiser could take a file, string or instance of its own class. You might then have code like:

class A(object):
    def __init__(self, f):
        if isinstance(f, A):
            # Just make a copy.
        elif isinstance(f, file):
            # initialise from the file
        else:
            # treat f as a string

Using EAFP here could cause all sorts of subtle problems as each initialisation path gets partially run before throwing an exception. Essentially this construction mimics function overloading and so isn't very Pythonic, but it can be useful if used with care.

As a side note, you can't do the file check in the same way in Python 3. You'll need something like isinstance(f, io.IOBase) instead.

like image 24
Scott Griffiths Avatar answered Oct 20 '22 22:10

Scott Griffiths


It is generally not good practice to have checks like this in your code at all unless you have special requirements.

In Python the typing is dynamic, why do you feel need to check whether the object is file like, rather than just using it as if it was a file and handling the resulting error?

Any check you can do is going to happen at runtime anyway so doing something like if not hasattr(fp, 'read') and raising some exception provides little more utility than just calling fp.read() and handling the resulting attribute error if the method does not exist.

like image 41
Tendayi Mawushe Avatar answered Oct 20 '22 22:10

Tendayi Mawushe


The dominant paradigm here is EAFP: easier to ask forgiveness than permission. Go ahead and use the file interface, then handle the resulting exception, or let them propagate to the caller.

like image 27
drxzcl Avatar answered Oct 20 '22 22:10

drxzcl