给定一个文件对象,如何确定它是以字节模式打开(read
返回bytes
)还是以文本模式打开(read
返回str
)?它应该与阅读和写作一起工作。
换句话说:
>>> with open('filename', 'rb') as f:
... is_binary(f)
...
True
>>> with open('filename', 'r') as f:
... is_binary(f)
...
False
(Another question听起来不相关。那个问题是关于猜测某个文件是否为二进制文件而不是内容。)
答案 0 :(得分:14)
文件对象有.mode
attribute:
def is_binary(f):
return 'b' in f.mode
这限制了对文件的测试;内存文件对象(如TextIO
和BytesIO
)没有该属性。您还可以测试appropriate abstract base classes:
import io
def is_binary(f):
return isinstance(f, (io.RawIOBase, io.BufferedIOBase))
或反向
def is_binary(f):
return not isinstance(f, io.TextIOBase)
答案 1 :(得分:0)
对于作为阅读打开的流,确定其模式的最可靠方法可能是从读取:
def is_binary(f):
return isinstance(f.read(0), bytes)
通过它确实有一个警告,如果流已经关闭(它可能会引发IOError
)它将无法工作它会可靠地确定任何自定义文件类对象的二进制性适当的io
ABCs,也不提供mode
属性。
如果只需要Python 3支持,那么在字节和文本之间有明确的区别的情况下,也可以确定可写流的文本/二进制模式:
def is_binary(f):
read = getattr(f, 'read', None)
if read is not None:
try:
data = read(0)
except (TypeError, ValueError):
pass # ValueError is also a superclass of io.UnsupportedOperation
else:
return isinstance(data, bytes)
try:
# alternatively, replace with empty text literal
# and swap the following True and False.
f.write(b'')
except TypeError:
return False
return True
除非你经常测试一个流是否处于二进制模式(这是不必要的,因为流的二进制不应该在对象的生命周期内改变),我怀疑由于广泛使用而导致任何性能缺陷捕捉异常将是一个问题(你当然可以针对更有可能的路径进行优化)。
答案 2 :(得分:-3)
有一个名为mimetypes的库,其中guess_type返回返回值。返回值是一个元组(类型,编码),其中类型为None,如果类型无法猜测(缺失或未知后缀)或字符串形式'type /子类型'
import mimetypes
file= mimetypes.guess_type(file)