问题描述
Python有几个io基类,包括
IOBase
RawIOBase
BufferedioBase
TextIOBase
以及几个派生的io类:
FileIO
BytesIO
现在,当我创建一个BytesIO
对象时,mro为:
[<class '_io.BytesIO'>,<class '_io._BufferedioBase'>,<class '_io._IOBase'>,<class 'object'>]
当我创建一个FileIO
对象时,mro为:
[<class '_io.FileIO'>,<class '_io._RawIOBase'>,<class 'object'>]
这非常简单。
但是,当我打开一个二进制文件以使用内置open进行写入时,我得到了mro:
[<class '_io.BufferedWriter'>,<class 'object'>]
不是根据最小惊奇原则打开要返回FileIO
对象的文件的命令吗?
我刚刚编写了一个接受BytesIO
或文件的方法,但我偶然发现了我的if isinstance(io.FileIO) ...
子句。
FileIO
对象和open返回的对象之间有什么区别?
解决方法
主要区别在于FileIO
继承自RawIOBase
类,该类提供了对OS级API的低级访问,但是open
函数返回了BufferedIOBase
继承者,在一般情况下(我认为)更合适)。作为副作用,FileIO
可以与OS级别的文件描述符一起用作名称(open
仅允许类似路径的文件)。因此,FileIO
提供了更灵活的API来处理二进制文件或流(例如,重新使用内存等),而open
却没有。有关差异here的更多信息。
具有象征意义的是-open
通常是用于锉刀的瑞士刀,FileIO
是外科医生的手术刀。
因此,对于您的问题,可能是isinstance
不是正确的选择,或者使用“鸭型”方法并检查对象是否具有必要的方法(或者使用另一种类型进行检查)可能更好。 isinstance
,例如IOBase
(如果它满足您的需求)。您也可以使用对象的readable()
,seekable()
,writable()
方法检查必要条件