How to make a file-like class work with “isinstance(cls, io.IOBase)”?
似乎检查
但是,在定义自己的类似文件的类时,它似乎不起作用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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' |
我该如何运作?
检查
一种不同的方法是使用抽象基类。 Python有许多内置的,但是目前还没有一个可以与
每周的Python模块Webiste很好地解释了如何使用
为了说明如何将其应用于您的案例,您可以定义一个这样的ABC及其所有抽象方法,从而强制派生类定义所有它们以便实例化:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | from abc import ABCMeta, abstractmethod class ABCFileLike(metaclass=ABCMeta): @abstractmethod def __init__(self): pass @abstractmethod def write(self, line): pass @abstractmethod def close(self): pass @abstractmethod def flush(self): pass |
然后,您可以从中派生自己的具体类,并确保提供所有抽象方法的实现。 (如果未全部定义它们,则尝试进行实例化时将引发
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | class FileLike(ABCFileLike): """ Concrete implementation of a file-like class. (Meaning all the abstract methods have an implementation.) """ def __init__(self): pass def write(self, line): print("Written:", line) def close(self): pass def flush(self): pass print(isinstance(FileLike(), ABCFileLike)) # -> True |
您甚至可以通过向新的元类注册现有的类来添加现有类:
1 2 3 4 5 6 | import io print(isinstance(io.IOBase(), ABCFileLike)) # -> False ABCFileLike.register(io.IOBase) print(isinstance(io.IOBase(), ABCFileLike)) # -> True |
在
当然,如果接收端未遵循鸭式输入,例如像您在此处那样尝试通过
最后,一个小小的风格:不要在类中没有显式继承任何空括号。它们是多余的。