2017-11-27 5 views
2

オブジェクトがファイルであるかどうかを確認するPython 2/3互換の方法はありますか?オブジェクトがPython 2および3のファイルであるかどうかをチェック

オブジェクトfilehandlerが実際にfileオブジェクトであるかどうかを確認する必要があります。このコードは、私が

isinstance(filehandler, file) 

しかしfile is not part of Python 3を行うことができますのPython 2ではPythonの2と3の両方で実行する必要があるので、Pythonのthis answerによると3

を実行すると、このコードはPythonで、NameErrorを上げます3 io.IOBaseは、オブジェクトがファイルであるかどうかを調べるのにPython 2のfileはサブクラスio.IOBaseを持たないので、isinstance(filehandler, io.IOBase)は機能しません。

私はをやって思ったが、私は、Python 3

でそれを実行したときには、まだNameErrorを与えるのPython 2.7と3の両方と互換性があり、これを行う方法はありますか?

答えて

1

これを行う最も一般的な方法は、Python 3でhasattrをチェックすることです。そこで、Pythonのバージョンをチェックするチェックを追加し、それに応じて正しい関数を実行します。

import sys 

def isFile(f): 
    return isinstance(f,file) if sys.version_info[0] == 2 else hasattr(f, 'read')   

f = open("post.php","r") 
print(isFile(f)) 
print(isFile(10)) 

また、lambdaを使用することもできますが、わかりにくいです。

isFile = lambda f:isinstance(f,file) if sys.version_info[0] == 2 else hasattr(f, 'read') 
+0

'lambda 'のポイントは無名関数なので、名前付き関数が必要な場合は' def'を使わない理由はありません。はるかに明瞭ではるかに読みやすい – jpyams

-1

理由だけではなく、あなたがしたい場合は、他のいくつかのエラーハンドラを追加することができますが、それが何をすべき

try: 
    #check in py3 
except: 
    #check in py2 

このような何かをしません。

+0

毛布 'except:'正しいのではなく、 'except NameError:'を意味すると思いますか? – SethMMorton

+0

はい、それは確かにあなたが得るだろうと確信している場合はおそらくより安全でしょう – SuperStew

+1

それはあなたがすべてをキャッチしようとするよりもあなたが得ると知っているものをキャッチする方が良いです。他の予期せぬ理由のためにコードが 'ValueError'を投げた場合、' except'というブランケットがエラーをデバッグするのが難しくなると思います。 – SethMMorton

0

これは私が使用した回避策だった:.pyファイルの先頭に、私が追加:

import sys 

if sys.version_info[0] == 3: 
    from io import IOBase 
    file = IOBase 

をPythonの3が使用されているのであれば、IOBaseするfileを設定します。今度はisinstance(filehandler, file)はPython 3で正しく動作し、Python 2では常に同じように動作します。

もちろん、この解決策は、IOBasefileのPython 3バージョンであるように見えるため、非常にハックし混乱します。しかし、それは問題を解決します。

関連する問題