Python中的文件对象是什么类型?

23

我该如何使用isinstance来确定文件对象的“类型”,例如在这个表达式中:

>>> open(file)

1
判断open(file)的类型是什么意思?你是指文件中文本的类型(例如int、string)吗? - Vedaad Shakib
6
如果你在Python3中遇到这个问题,需要适当地使用类型提示,可以导入typing模块中的TextIO(例如在“前言”中使用 from typing import TextIO,然后在代码中使用file_handle: TextIO = open(...))。请注意不要改变原文意思。 - mutableVoid
4个回答

28
在Python 3.x中,普通文件对象的类型为io.TextIOWrapper
>>> type(open('file.txt'))
<class '_io.TextIOWrapper'>

>>> from io import TextIOWrapper
>>> isinstance(open('file.txt'), TextIOWrapper)
True

在Python 2.x中,所有文件对象都是file类型的:
>>> type(open('file.txt'))
<type 'file'>

>>> isinstance(open('file.txt'), file)
True

4
大多数时候,你并不关心细节。你只需要一个可迭代的行对象,或者它有一个read方法或write方法,或者其他一些与文件接口相关的特性。通常你应该检查这些特性,方法是尝试使用这个对象像读写文件一样,如果它不支持你需要的接口则捕获错误。 - user2357112
1
FYI,以二进制模式打开文件open('file.txt', 'rb')会得到类型为<class '_io.BufferedReader'>的结果。 - Rick
3
如果您以默认/文本模式打开文件,则会返回TextIOWrapper,如果以二进制('b')模式打开,则会返回BufferedReader。因此,您可以单独检查它们,或者如果想要捕获两者,可以使用它们的超类IOBase - AndrewWhalan

10
可以从IO 类层次结构中选择自己的偏好。本答案基于user2555451及其评论给出的前一个答案。本答案末尾有一行总结。
对于文本文件,可以使用io.TextIOBase
>>> import io

>>> type(f := open('/tmp/foo', 'w'))
<class '_io.TextIOWrapper'>
>>> isinstance(f, io.TextIOBase)
True

>>> f.__class__.__bases__
(<class '_io._TextIOBase'>,)
>>> f.__class__.__mro__
(<class '_io.TextIOWrapper'>, <class '_io._TextIOBase'>, <class '_io._IOBase'>, <class 'object'>)

对于文本文件,请避免使用io.TextIOWrapper,因为它无法处理io.StringIO

>>> isinstance(io.StringIO('foo'), io.TextIOWrapper)
False
>>> isinstance(io.StringIO('foo'), io.TextIOBase)
True

对于二进制文件io.BufferedIOBase可以接受。
>>> import io

>>> type(f := open('/tmp/foo', 'wb'))
<class '_io.BufferedWriter'>
>>> isinstance(f, io.BufferedIOBase)
True

>>> f.__class__.__bases__
(<class '_io._BufferedIOBase'>,)
>>> f.__class__.__mro__
(<class '_io.BufferedWriter'>, <class '_io._BufferedIOBase'>, <class '_io._IOBase'>, <class 'object'>)

对于二进制文件,避免使用 io.BufferedReaderio.BufferedWriter,因为它们无法用于io.BytesIO
>>> isinstance(io.BytesIO(b'foo'), io.BufferedReader)
False
>>> isinstance(io.BytesIO(b'foo'), io.BufferedWriter)
False
>>> isinstance(io.BytesIO(b'foo'), io.BufferedIOBase)
True

为了支持文本和二进制文件,可以使用io.IOBase
>>> import io

>>> isinstance(open('/tmp/foo', 'w'), io.IOBase)
True
>>> isinstance(open('/tmp/foo', 'wb'), io.IOBase)
True

总之,我通常会选择io.TextIOBase来处理文本文件,io.BufferedIOBase来处理二进制文件,以及io.IOBase来处理不特定文件。


1

open的文档所述:

打开一个文件,返回一个file类型的对象,该类型在文件对象中有描述。

因此,open返回一个file,您应该使用isinstance(foo, file)


0

它的类型是file。你可以通过type(open("file","w"))的输出来确定。


4
这已经过时了。 - Carsten

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接