FileIO对象和open返回的对象之间的区别文件名,模式

问题描述

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()方法检查必要条件