[Python] ファイルが存在するかどうかを確認するには?


Answers

あなたはos.path.exists関数を持っています:

import os.path
os.path.exists(file_path)

これは、ファイルとディレクトリの両方に対してTrueを返しますが、代わりにos.path.isfileを使用して、ファイルであるかどうかをテストできます。 それはシンボリックリンクに続く。

Question

try文を使わずにファイルが存在するかどうかを調べるには?




Additionally, os.access() :

if os.access("myfile", os.R_OK):
    with open("myfile") as fp:
        return fp.read()

Being R_OK , W_OK , and X_OK the flags to test for permissions ( doc ).




if os.path.isfile(path_to_file):
    try: 
        open(path_to_file)
            pass
    except IOError as e:
        print "Unable to open file"

Raising exceptions is considered to be an acceptable, and Pythonic, approach for flow control in your program. Consider handling missing files with IOErrors. In this situation, an IOError exception will be raised if the file exists but the user does not have read permissions.

SRC: http://www.pfinn.net/python-check-if-file-exists.html




try / exceptとisfile()間に意味のある機能上の相違があるようには見えないので、どちらを使うのがよいでしょうか。

ファイルが存在する場合は、そのファイルを読みたい場合は、

try:
    f = open(filepath)
except IOError:
    print 'Oh dear.'

しかし、ファイルが存在する場合に名前を変更したいので、ファイルを開く必要がない場合は、

if os.path.isfile(filepath):
    os.rename(filepath, filepath + '.old')

ファイルに書き込む場合は、ファイルが存在しない場合は、

# python 2
if not os.path.isfile(filepath):
    f = open(filepath, 'w')

# python 3, x opens for exclusive creation, failing if the file already exists
try:
    f = open(filepath, 'wx')
except IOError:
    print 'file already exists'

ファイルロックが必要な場合は、別の問題です。




import os
os.path.exists(path) # returns whether the path (dir or file) exists or not
os.path.isfile(path) # returns whether the file exists or not



import os.path

if os.path.isfile(filepath):



Python 3.4以降には、オブジェクト指向パスモジュールpathlibがあります。 この新しいモジュールを使用すると、ファイルが次のように存在するかどうかを確認できます。

import pathlib
p = pathlib.Path('path/to/file')
if p.is_file():  # or p.is_dir() to see if it is a directory
    # do stuff

ファイルを開くときにtry/exceptブロックを使用することができます(通常はそうするべきです):

try:
    with p.open() as f:
        # do awesome stuff
except OSError:
    print('Well darn.')

pathlibモジュールには便利なglobbing、ファイルの所有者のチェック、簡単なパスの結合など、たくさんのクールなものがあります。チェックアウトする価値があります。 古いPython(バージョン2.6以降)を使用している場合でも、piplibをpipでインストールできます。

# installs pathlib2 on older Python versions
# the original third-party module, pathlib, is no longer maintained.
pip install pathlib2

次に、次のようにインポートします。

# Older Python versions
import pathlib2 as pathlib



import os
#Your path here e.g. "C:\Program Files\text.txt"
#For access purposes: "C:\\Program Files\\text.txt"
if os.path.exists("C:\..."):   
    print "File found!"
else:
    print "File not found!"

osをインポートすると、オペレーティングシステムで標準のアクションを簡単にナビゲートして実行できます。

参考shareも参照share

高レベルの操作が必要な場合は、 shutil使用してshutil




Here's a 1 line Python command for the Linux command line environment. I find this VERY HANDY since I'm not such a hot Bash guy.

python -c "import os.path; print os.path.isfile('/path_to/file.xxx')"

I hope this is helpful.




You can use the "OS" library of Python:

>>> import os
>>> os.path.exists("C:\\Users\\####\\Desktop\\test.txt") 
True
>>> os.path.exists("C:\\Users\\####\\Desktop\\test.tx")
False



あなたはこれを試すことができます(より安全):

try:
    # http://effbot.org/zone/python-with-statement.htm
    # 'with' is safer to open a file
    with open('whatever.txt') as fh:
        # Do something with 'fh'
except IOError as e:
    print("({})".format(e))

出力は次のようになります。

([Errno 2]そのようなファイルやディレクトリはありません: 'whatever.txt')

結果に応じて、プログラムはそこから実行し続けることも、必要に応じて停止するようにコードすることもできます。




I'm the author of a package that's been around for about 10 years, and it has a function that addresses this question directly. Basically, if you are on a non-Windows system, it uses Popen to access find . However, if you are on Windows, it replicates find with an efficient filesystem walker.

The code itself does not use a try block… except in determining the operating system and thus steering you to the "Unix"-style find or the hand-buillt find . Timing tests showed that the try was faster in determining the OS, so I did use one there (but nowhere else).

>>> import pox
>>> pox.find('*python*', type='file', root=pox.homedir(), recurse=False)
['/Users/mmckerns/.python']

And the doc…

>>> print pox.find.__doc__
find(patterns[,root,recurse,type]); Get path to a file or directory

    patterns: name or partial name string of items to search for
    root: path string of top-level directory to search
    recurse: if True, recurse down from root directory
    type: item filter; one of {None, file, dir, link, socket, block, char}
    verbose: if True, be a little verbose about the search

    On some OS, recursion can be specified by recursion depth (an integer).
    patterns can be specified with basic pattern matching. Additionally,
    multiple patterns can be specified by splitting patterns with a ';'
    For example:
        >>> find('pox*', root='..')
        ['/Users/foo/pox/pox', '/Users/foo/pox/scripts/pox_launcher.py']

        >>> find('*shutils*;*init*')
        ['/Users/foo/pox/pox/shutils.py', '/Users/foo/pox/pox/__init__.py']

>>>

The implementation, if you care to look, is here: https://github.com/uqfoundation/pox/blob/89f90fb308f285ca7a62eabe2c38acb87e89dad9/pox/shutils.py#L190




import os
path = /path/to/dir

root,dirs,files = os.walk(path).next()
if myfile in files:
   print "yes it exists"

This is helpful when checking for several files. Or you want to do a set intersection/ subtraction with an existing list.




If the file is for opening you could use one of the following techniques:

>>> with open('somefile', 'xt') as f: #Using the x-flag, Python3.3 and above
...     f.write('Hello\n')

>>> if not os.path.exists('somefile'): 
...     with open('somefile', 'wt') as f:
...         f.write("Hello\n")
... else:
...     print('File already exists!')



2017/12/22

ほぼすべての可能な方法が既存の回答(少なくともPython 3.4のものが追加された)に(少なくとも1つ)リストされていますが、私はすべてをまとめてグループ化しようとします。

:私が投稿しようとしているPythonの標準ライブラリコードはすべて、バージョン3.5.3に属しています(doc引用符はバージョン3固有のものです)。

問題文

  1. チェックファイル( 議論 :フォルダー( "特別"ファイル)?)存在
  2. try / except / else / finallyブロックは使用しないでください

可能な解決策

  1. [Python]:os.path。 存在するpathos.path.isfileos.path.isdiros.path.lexistsような他の関数ファミリのメンバもやや異なる挙動をチェックする)

    os.path.exists(path)
    

    pathが既存のパスまたは開いているファイル記述子を参照する場合はTrue返します。 壊れたシンボリックリンクに対してFalseを返します。 一部のプラットフォームでは、 パスが物理的に存在する場合でも、要求されたファイルに対してos.stat()を実行する権限が与えられていない場合、この関数はFalse返します。

    すべて良いですが、インポートツリーに従っている場合:

    • os.path - posixpath.pyntpath.py

      • genericpath.py 、行〜#20 +

        def exists(path):
            """Test whether a path exists.  Returns False for broken symbolic links"""
            try:
                st = os.stat(path)
            except os.error:
                return False
            return True
        

    os.stat()周りのtry/exceptブロックos.stat() os.stat() 。 だから、あなたのコードはtry/except free try/exceptますが、フレームスタックの下位には少なくともそのようなブロックが1つあります。 これは他の関数( os.path.isfile を含む )にも当てはまります。

    1.1。 [Python]:pathlib.Path。 is_file ()

    • これは、より扱いやすい(そしてより多くのpython icの)経路を扱う方法ですが、
    • フードの下では、 まったく同じことをします( pathlib.py 、行〜#1330 )。

      def is_file(self):
          """
          Whether this path is a regular file (also True for symlinks pointing
          to regular files).
          """
          try:
              return S_ISREG(self.stat().st_mode)
          except OSError as e:
              if e.errno not in (ENOENT, ENOTDIR):
                  raise
              # Path doesn't exist or is a broken symlink
              # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
              return False
      
  2. [Python]:ステートメントコンテキストマネージャを使用 。 どちらか:

    • 一つ作る:

      class Swallow:  # Dummy example
          swallowed_exceptions = (FileNotFoundError,)
      
          def __enter__(self):
              print("Entering...")
      
          def __exit__(self, exc_type, exc_value, exc_traceback):
              print("Exiting:", exc_type, exc_value, exc_traceback)
              return exc_type in Swallow.swallowed_exceptions  # only swallow FileNotFoundError (not e.g. TypeError - if the user passes a wrong argument like None or float or ...)
      
      • そしてその使い方 - 私はisfile振る舞いを再現します(これは目的を示すためのものであり、 本番用にそのようなコードを書くことはしないでください)。

        import os
        import stat
        
        
        def isfile_seaman(path):  # Dummy func
            result = False
            with Swallow():
                result = stat.S_ISREG(os.stat(path).st_mode)
            return result
        
    • [Python]:contextlibを使用してください 抑制*例外 - 例外を選択的に抑制するために特別に設計された


    しかし、それらはtry/except/else/finallyブロック上のラッパーであるように見えます。 [Python]: withステートメントは次のように述べています:

    これにより、一般的なtry ... except ... finally使用パターンがカプセル化され、再利用が容易になります。

  3. ファイルシステムのトラバース関数(および一致する項目の検索結果)


    これらはフォルダを繰り返し処理するので(ほとんどの場合)、私たちの問題では非効率的です(@ shadowRangerが指摘しているように、例外はありません)。 場合によっては、ファイル名の処理が必要な場合もあります。

  4. [Python]:os。 その挙動がos.path.exists近い(実際には2 番目の引数のために実際にはより広くなります) アクセスpath、mode、*、dir_fd = None、effective_ids = False、follow_symlinks = True

    • ドキュメントの状態に応じて、ユーザー権限によってファイルの「可視性」が制限されることがあります。

      ...呼び出すユーザーが指定されたパスへのアクセス権を持っているかどうかをテストしますモードF_OKでパスの存在をテストする必要があります...

    os.access("/tmp", os.F_OK)
    

    また、私はCで作業しているので、このメソッドも使用しています。これは、 ネイティブAPIを (「 $ {PYTHON_SRC_DIR} /Modules/posixmodule.c 」を介して)呼び出しますが、可能なユーザーのためのゲートも開きますエラーが発生し 、他の亜種と同じようにPython ICではありません。 @AaronHallが正しく指摘したように、あなたが何をしているのか分からない限り、それを使用しないでください:

    :ネイティブAPIを呼び出すことも可能です。[Python]: ctypes - Python用の外部関数ライブラリですが、ほとんどの場合、より複雑です。

    Win固有): msvcr *vcruntime * )は[MSDN]:_access、_waccess関数ファミリをエクスポートするので、ここにその例を示します。

    Python 3.5.3 (v3.5.3:1880cb95a742, Jan 16 2017, 16:02:32) [MSC v.1900 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import os, ctypes
    >>> ctypes.CDLL("msvcrt")._waccess(u"C:\\Windows\\System32\\cmd.exe", os.F_OK)
    0
    >>> ctypes.CDLL("msvcrt")._waccess(u"C:\\Windows\\System32\\___cmd.exe", os.F_OK)
    -1
    

    • それは良い習慣ではありませんが、私は呼び出しでos.F_OKを使用していますが、それは分かりやすくするためです(その値は0です
    • 私は同じコードがPython3Python2で動作するように_waccess使用していますUnicodeに関連する違いにもかかわらず)
    • これは非常に特定の分野を対象としていますが、これまでの回答には言及されていません


    LnxUbtu(16 x64) )対応のもの:

    Python 3.5.2 (default, Nov 17 2016, 17:05:23)
    [GCC 5.4.0 20160609] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import os, ctypes
    >>> ctypes.CDLL("/lib/x86_64-linux-gnu/libc.so.6").access(b"/tmp", os.F_OK)
    0
    >>> ctypes.CDLL("/lib/x86_64-linux-gnu/libc.so.6").access(b"/tmp1", os.F_OK)
    -1
    

    • libcのパス( "/lib/x86_64-linux-gnu/libc.so.6" )をハードコードするのではなく、システムによって変わる可能性がありますが、おそらくNone (または空の文字列)はCDLLコンストラクタに渡すことができます( ctypes.CDLL(None).access(b"/tmp", os.F_OK) )。 [男]によると:DLOPEN(3)

      filenameがNULLの場合、返されるハンドルはメインプログラムのハンドルです。 dlsym ()に与えられると、このハンドルは、プログラム起動時にロードされたすべての共有オブジェクト、次にdlopen ()によってロードされたすべての共有オブジェクトをフラグRTLD_GLOBALで検索します。

      • メイン(現在の)プログラム( python )はlibcとリンクしているので、そのシンボル( accessを含む)がロードされます
      • これは、 mainPy_Mainなどの関数が利用可能であるため、注意して処理する必要があります。 それらを呼び出すことは悲惨な影響を与える可能性があります(現在のプログラムで)
      • msvcrt.dllはデフォルトで%PATH%にある"%SystemRoot%\ System32"にありますので、これはWinにも当てはまりません(しかしそれほど大きな問題はありません )。 私はさらに物事を取って、 Winでこの動作を複製したい(パッチを提出する)が、実際には[MSDN]:GetProcAddress関数エクスポートされたシンボルしか見ることができないので、誰かがmain実行可能ファイルの関数を__declspec(dllexport) (どうして地球上で普通の人がそうするのでしょうか?)、メインプログラムは読み込み可能ですがかなり使用できません
  5. ファイルシステム機能を備えたサードパーティのモジュールをインストールする

    ほとんどの場合、上記の方法の1つに依存しています(おそらくわずかなカスタマイズで)。
    GitHub):Python for Windows(pywin32)Extensionsは、 WINAPI上Pythonラッパーです。

    しかし、これは回避策に似ているので、私はここでやります。

  6. 別の( 色あせ )回避策( gainarie )は、 sysadminのアプローチです( Pythonをラッパーとして使用してシェルコマンドを実行します)

    • 勝つ

      (py35x64_test) e:\Work\Dev\\q000082831>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" -c "import os; print(os.system('dir /b \"C:\\Windows\\System32\\cmd.exe\" > nul 2>&1'))"
      0
      
      (py35x64_test) e:\Work\Dev\\q000082831>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" -c "import os; print(os.system('dir /b \"C:\\Windows\\System32\\cmd.exe.notexist\" > nul 2>&1'))"
      1
      
    • LnxUbtu ):

      [cfati@cfati-ubtu16x64-0:~]> python3 -c "import os; print(os.system('ls \"/tmp\" > /dev/null 2>&1'))"
      0
      [cfati@cfati-ubtu16x64-0:~]> python3 -c "import os; print(os.system('ls \"/tmp.notexist\" > /dev/null 2>&1'))"
      512
      

ボトムライン

  • try / except / else / finallyブロックexcept使用してtry 。これにより、一連の厄介な問題が発生するのを防ぐことができます。 私が考えることができる反例はパフォーマンスです。そのようなブロックはコストがかかるので、毎秒何十万回も実行するはずのコードに配置しないようにしてください(ただし、ほとんどの場合、ディスクアクセス、それは事実ではない)。

最終的な注釈

  • 私はそれを最新に保つように努力します、どんな提案も歓迎です、私は答えになる有用なものを取り入れます



Links