Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a file-like class work with "isinstance(cls, io.IOBase)"?

It seems that checking isinstance(..., io.IOBase) is the 'correct' way to determine if an object is 'file-like'.

However, when defining my own file-like class, it doesn't seem to work:

import io

class file_like():

    def __init__(self):
        pass

    def write(self, line):
        print("Written:", line)

    def close(self):
        pass

    def flush(self):
        pass

print(isinstance(file_like(), io.IOBase))
# Prints 'False'

How can I make it work?

like image 678
kiri Avatar asked Oct 19 '25 10:10

kiri


1 Answers

isinstance(obj, some_class) just iterates up obj's inheritance chain, looking for some_class. Thus isinstance(file_like, io.IOBase), will be false, as your file_like class doesn't have io.IOBase in its ancestry. file_like doesn't designate an explicit parent, hence it implicitly inherits only from object. That's the only class - besides file_like itself - that will test positive for a file_like instance with isinstance().

What you are doing in file_like is defining the methods expected on a file-like object while not inheriting from any particular "file-like" class. This approach is called duck-typing, and it has many merits in dynamic languages, although it's more popular in others (e.g. Ruby) than Python. Still, if whatever you're providing your file_like instance to follows duck-typing, it should work, provided your file_like does in fact "quack like a file", i.e. behaves sufficiently like a file to not cause errors upon usage at the receiving end.

Of course, if the receiving end is not following duck-typing, for example tries to check types by isinstance() as you do here, this approach will fail.

Finally, a small stylistic nit: don't put empty parens on a class if it doesn't inherit anything explicitly. They are redundant.

like image 139
Dun Peal Avatar answered Oct 22 '25 01:10

Dun Peal