FileIO 对象与 open(filename, mode) 返回的对象的区别

Difference between FileIO object and object returned by open(filename, mode)

提问人:Wör Du Schnaffzig 提问时间:10/30/2020 更新时间:10/30/2020 访问量:738

问:

Python 有几个 io 基类,包括

IOBase
RawIOBase
BufferedIOBase
TextIOBase

以及几个派生的 IO 类:

FileIO
BytesIO

现在,当我创建一个对象时,mro 是:BytesIO

[<class '_io.BytesIO'>, <class '_io._BufferedIOBase'>, <class '_io._IOBase'>, <class 'object'>]

当我创建一个对象时,MRO 是:FileIO

[<class '_io.FileIO'>, <class '_io._RawIOBase'>, <class '_io._IOBase'>, <class 'object'>]

这很简单。

但是,当我使用内置的 open 打开二进制文件进行写入时,我得到 mro:

[<class '_io.BufferedWriter'>, <class '_io._BufferedIOBase'>, <class '_io._IOBase'>, <class 'object'>]

打开文件的命令难道不是根据最小意外原则返回对象吗? 我刚刚编写了一个接受 a 或 file 的方法,但我偶然发现了我的子句。 对象和 open 返回的对象有什么区别?FileIOBytesIOif isinstance(io.FileIO) ...FileIO

python-3.x 文件-io io isinstance 字节

评论


答:

2赞 Sergey Tsaplin 10/30/2020 #1

主要区别在于继承自提供对操作系统级 API 的低级访问的类,但该函数返回一个继承器,这在通用情况下更合适(我认为))。由于副作用可以与操作系统级别的文件描述符一起使用(仅允许类似路径)。因此,它提供了更灵活的 API 来处理二进制文件或流(例如,重新使用内存使用等),- 没有。有关差异的更多信息,请点击此处FileIORawIOBaseopenBufferedIOBaseFileIOopenFileIOopen

形象地说 - 是一把瑞士刀,用于锉刀,是外科医生的手术刀。openFileIO

因此,对于您的问题,可能是选择不正确,可能是最好使用“鸭子类型”方法并检查对象是否具有必要的方法(或使用其他类型进行检查,例如它是否满足了您的需求)。也可以使用对象的 、 、 方法来检查必要条件isinstanceisinstanceIOBasereadable()seekable()writable()

评论

0赞 Wör Du Schnaffzig 11/3/2020
感谢您的回答,尤其是指出可读()...等方法。背景:我用方法编写了一个类。如果给定一个文件,它将确定文件大小并将内容加载到内部缓冲区中。如果给定一个 BytesIO,它使用 getbuffer 来获取内容和大小,然后像另一种情况一样继续。根据您的鸭子打字建议,我需要检查是否存在 or .另一种可能性是检查并假设它是其他的。from_file(f: io.IOBase)f.getbuffer()f.nameBytesIOFileIO