2017-06-16 9 views
3

ファイルオブジェクトを指定すると、バイトモード(readbytesを返します)またはテキストモード(readstrを返します)で開くかどうかをどのように判断しますか?それは読書と書くことで動作するはずです。言い換えればファイルがバイナリモードまたはテキストモードで開かれているかどうかを確認するには?

>>> with open('filename', 'rb') as f: 
...  is_binary(f) 
... 
True 

>>> with open('filename', 'r') as f: 
...  is_binary(f) 
... 
False 

Another question関連の音ではないことを疑問は、ファイルは、それが内容だからバイナリであるかどうかを推測についてです。。)

答えて

9

ファイルオブジェクトは持っています.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) 
+0

優れ、また、ドキュメントのリンクに感謝し、IOモジュールに私を指しています。私はまた、今私が考えていることを....非常に表面的である用語集で、[ファイルオブジェクト](https://docs.python.org/3.6/glossary.html#term-file-object)の定義を見つけましたそれについては、おそらくちょうど読書を試み、それが失敗した場合に例外をキャッチする別のpythonic方法でしょう。 – jdm

+0

@jdm:cool!私がアクセプトマークを得るために追加したいものは何ですか?あなたが答えたものをマークしておらず、何も足りないものがないことを確認したいのであれば、それはいいですね:-) –

+0

いいえ、答えはすばらしく、確かに受け入れられます:-) – jdm

-2

guess_typeが戻り値の型がNoneのタプル(タイプ、エンコーディング)で返すMIMEタイプと呼ばれる1つのライブラリがありますがタイプが推測できない場合は、おそらく最も信頼性の高い方法を(見つからないか、不明な接尾辞)、またはストリームのために、フォームの文字列「タイプ/サブタイプ」

import mimetypes 
file= mimetypes.guess_type(file) 
+1

これはファイルの内容に関するものではありません。これはファイルのオープン方法です。質問を慎重に読んでください、彼らは具体的にこれが答えかもしれない別の質問を言いますが、*これはその質問ではありません*。 –

0

は読書としてオープンそれを介して

def is_binary(f): 
    return isinstance(f.read(0), bytes) 

は、それが確実にバイナリレベルを決定するであろう(IOErrorを上げることができる)ストリームがすでに閉じられていた場合、それは動作しませんという警告を持っている:そのモードを決定するために、実際はそれからを読むことですどちらも適切なioいろはから延びるも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 

を(ストリームのバイナリ・ネスは、オブジェクトの存続期間変更すべきではありませんので、不要である)バイナリモードであるかどうか、私はあなたが確かにするために最適化することができました(例外をキャッチするの広範な使用方法に起因するいかなるパフォーマンスの欠点が問題だろう疑いますしかし、尤度のパス)。

関連する問題