Python 如何使类似文件的类与";iInstance(cls,io.IOBase)“;?
似乎检查Python 如何使类似文件的类与";iInstance(cls,io.IOBase)“;?,python,file,class,isinstance,Python,File,Class,Isinstance,似乎检查isinstance(…,io.IOBase)是确定对象是否为“类似文件”的“正确”方法 但是,在定义我自己的类文件时,它似乎不起作用: 导入io 类文件\u like(): 定义初始化(自): 通过 def写入(自身,行): 打印(“书写:”,行) def关闭(自我): 通过 def冲洗(自): 通过 打印(isinstance(类文件(),io.IOBase)) #打印“假” 如何使其工作?isinstance(obj,某些类)只是迭代obj的继承链,寻找某些类。因此,isinst
isinstance(…,io.IOBase)
是确定对象是否为“类似文件”的“正确”方法
但是,在定义我自己的类文件时,它似乎不起作用:
导入io
类文件\u like():
定义初始化(自):
通过
def写入(自身,行):
打印(“书写:”,行)
def关闭(自我):
通过
def冲洗(自):
通过
打印(isinstance(类文件(),io.IOBase))
#打印“假”
如何使其工作?isinstance(obj,某些类)
只是迭代obj的继承链,寻找某些类。因此,isinstance(file_like,io.IOBase)
将为false,因为您的file_like
类在其祖先中没有io.IOBase
<代码>文件\u like
不指定显式父对象,因此它仅隐式地从对象继承。除了file\u like
本身之外,这是唯一一个使用isinstance()对file\u like
实例测试为阳性的类
您在file\u like
中所做的是定义类文件对象上所需的方法,而不是从任何特定的“类文件”类继承。这种方法被称为,它在动态语言中有许多优点,尽管它在其他语言(例如Ruby)中比Python更受欢迎。尽管如此,如果您提供的类文件
实例遵循duck类型,只要您的类文件
确实“像文件一样嘎嘎”,即其行为足够像文件,在接收端使用时不会导致错误,那么它应该可以工作
当然,如果接收端没有遵循duck类型,例如,像您在这里所做的那样尝试通过isinstance()
检查类型,那么这种方法将失败
最后,一个小的风格错误:如果类没有显式继承任何内容,则不要将空paren放在类上。它们是多余的。检查isinstance(something,io.IOBase)
只检查something
是否是io.IOBase
的实例或派生自它的类-所以我不明白你从哪里误解了这是确定对象是否“类似文件”的“正确”方法
另一种方法是使用抽象基类。Python有很多,但目前还没有一个可以与isinstance()
一起使用的“类文件”。但是,您可以使用中概述的abc
模块定义自己的代码
webiste有一个使用abc
模块完成类似操作的方法。这个被高度评价的问题显示了一种定义你自己ABC的类似方式
为了说明如何将其应用到您的案例中,您可以定义这样的ABC及其所有抽象方法,从而强制派生类定义所有这些方法以便实例化:
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
然后,您可以从中派生自己的具体类,确保提供所有抽象方法的实现。(如果您没有全部定义它们,那么如果尝试实例化它,将引发TypeError
。)
您甚至可以通过使用新元类注册现有类来向其添加这些类:
import io
print(isinstance(io.IOBase(), ABCFileLike)) # -> False
ABCFileLike.register(io.IOBase)
print(isinstance(io.IOBase(), ABCFileLike)) # -> True
谢谢你的回答。它澄清了我的许多问题。也谢谢你的风格说明,我相信这是从需要paren的函数遗留下来的。我会记下来的
import io
print(isinstance(io.IOBase(), ABCFileLike)) # -> False
ABCFileLike.register(io.IOBase)
print(isinstance(io.IOBase(), ABCFileLike)) # -> True