2017-06-16 93 views
3

給定一個文件對象,如何確定它是否以字節模式打開(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這聽起來相關不是這個問題是有關猜測文件是否是二進制或不是從它的內容。)

回答

9

File對象有.mode attribute

def is_binary(f): 
    return 'b' in f.mode 

這將測試限制爲文件,內存中的文件對象TextIOBytesIO沒有該屬性。您也可以測試爲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) 
+0

非常好,也感謝文檔鏈接,並指向我的io模塊。我只在詞彙表中找到了[文件對象](https://docs.python.org/3.6/glossary.html#term-file-object)的定義,這是非常膚淺的。此外,現在我認爲關於它,另一種pythonic方式可能只是嘗試閱讀,如果失敗則會發生異常。 – jdm

+0

@jdm:cool!您希望我添加什麼來獲得接受標記? (如果你沒有將答案標記爲已接受,只是想確保沒有遺漏任何東西就沒關係):-) –

+0

不,答案很好,絕對接受:-) – jdm

-2

有一個稱爲MIME類型一個圖書館,guess_type返回返回值是一個元組(類型,編碼),其中類型是無如果該類型不能被猜到(缺失的或未知後綴)或形式的字符串「類型/子類型」

import mimetypes 
file= mimetypes.guess_type(file) 
+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 

除非你是經常測試,如果流是二進制模式還是不行(這是不必要的,因爲流的二進制不應該在對象的生命週期中改變),我懷疑由於廣泛使用捕捉異常導致的性能缺陷將是一個問題(你當然可以優化儘管如此)。

相關問題