Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: determining if an object is file-like? [duplicate]

Tags:

python

types

file

I'm writing some unit tests (using the unittest module) for my application, and want to write something which can verify that a method I'm calling returns a "file-like" object. Since this isn't a simple isinstance call, I wonder what the best-practice would be for determining this?

So, in outline:

possible_file = self.dao.get_file("anotherfile.pdf")
self.assertTrue(possible_file is file-like)

Perhaps I have to care which specific interface this file object implements, or which methods that make it file-like I want to support?

Thanks,

R

like image 211
Richard J Avatar asked Aug 10 '10 15:08

Richard J


2 Answers

There is no "official definition" of what objects are "sufficiently file-like", because the various uses of file-like objects have such different requirements -- e.g., some only require read or write methods, other require some subset of the various line-reading methods... all the ways to some requiring the fileno method, which can't even be supplied by the "very file-like objects" offered by StringIO and cStringIO modules in the standard library. It's definitely a question of "shades of gray", not a black-and-white taxonomy!

So, you need to determine which methods you need. To check for them, I recommended defining your own FileLikeEnoughForMe abstract base class with abstractmethod decorators, and checking the object with an isinstance for that class, if you're on Python 2.6 or better: this is the recommended idiom these days, rather than a bunch of hasattr checks which would be less readable and more complex (when properly beefed up with checks that those attributes are actually methods, etc;-).

like image 173
Alex Martelli Avatar answered Sep 28 '22 10:09

Alex Martelli


The classical Python mentality is that it's easier to ask forgiveness than permission. In other words, don't check, catch the exception caused by writeing to it.

The new way is to use an IO abstract base class in an isinstance check. This was introduced when people realised that duck typing is awesome, but sometimes you really do want an instance check.

In your case (unittesting), you probably want to try it and see:

thingy = ...
try:
    thingy.write( ... )
    thingy.writeline( ... )
    ...
    thingy.read( )
except AttributeError:
    ...
like image 22
Katriel Avatar answered Sep 28 '22 11:09

Katriel