python 파이썬 - 파일이 예외없이 존재하는지 어떻게 확인합니까?





유무 리스트 (25)


파일을 여는 경우 다음 기술 중 하나를 사용할 수 있습니다.

>>> 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!')

최신 정보

그냥 혼란을 피하기 위해 내가 가진 대답을 기반으로, 현재 답변은 주어진 이름 으로 파일 이나 디렉토리를 찾습니다 .

try 문을 사용하지 않고 파일이 존재하는지 여부를 어떻게 알 수 있습니까?




tryexcept 문을 사용 try 것이 항상 권장되지만, 다음과 같은 몇 가지 가능성이 있습니다 (개인적으로 좋아하는 os.access 사용).

  1. 파일을 열어보십시오 :

    파일을 열면 항상 파일의 존재를 확인합니다. 다음과 같이 함수를 만들 수 있습니다.

    def File_Existence(filepath):
        f = open(filepath)
        return True
    

    False이면, 이후 버전의 Python에서 처리되지 않은 IOError 또는 OSError로 실행이 중지됩니다. 예외를 잡으려면 try except 절을 사용해야합니다. 물론, 당신은 항상 try except` 문을 사용할 수 있습니다. (저를 생각하게 해준 hsandt 에게 감사드립니다) :

    def File_Existence(filepath):
        try:
            f = open(filepath)
        except IOError, OSError: # Note OSError is for later versions of Python
            return False
    
        return True
    
  2. 사용 os.path.exists(path):

    이것은 당신이 지정한 것의 존재를 검사 할 것입니다. 그러나 파일 디렉토리를 검사하여 사용 방법에주의하십시오.

    import os.path
    >>> os.path.exists("this/is/a/directory")
    True
    >>> os.path.exists("this/is/a/file.txt")
    True
    >>> os.path.exists("not/a/directory")
    False
    
  3. 사용 os.access(path, mode):

    그러면 파일에 대한 액세스 권한이 있는지 여부가 확인됩니다. 권한을 확인합니다. os.py 문서를 기반으로 입력 os.F_OK하면 경로 존재 여부를 확인합니다. 그러나이를 사용하면 보안 허점이 생길 수 있습니다. 누군가가 권한 확인 및 파일 열기 사이의 시간을 사용하여 파일을 공격 할 수 있기 때문입니다. 대신 권한을 확인하는 대신 파일을 열어보아야합니다. ( EAFPLBYP ). 나중에 파일을 열지 않고 파일의 존재 여부 만 확인하면이 파일을 사용할 수 있습니다.

    어쨌든, 여기 :

    >>> import os
    >>> os.access("/is/a/file.txt", os.F_OK)
    True
    

또한 파일의 존재 여부를 확인할 수없는 두 가지 방법이 있음을 언급해야합니다. 문제는 permission denied또는 것 no such file or directory입니다. 당신이 잡는다면 IOError, IOError as e(내 첫 번째 옵션처럼)을 설정하고 , print(e.args)당신이 당신의 이슈를 희망적으로 결정할 수 있도록 입력 하십시오. 도움이되기를 바랍니다! :)




당신은 이것을 시도 할 수 있습니다 (더 안전한) :

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')

그런 다음 결과에 따라 프로그램을 계속 실행하거나 원하는 경우 코드를 중지 할 수 있습니다.




검사하고있는 이유 if file_exists: open_it() 과 비슷한 것을 할 수 if file_exists: open_it() 열려는 시도를 둘러싼 try 를 사용하는 것이 더 안전합니다. 검사하고 나서 열면 파일이 삭제되거나 이동되거나 검사 할 때와 열려고 할 때 사이에 위험이 있습니다.

파일을 바로 열지 않으려면 os.path.isfile 사용할 수 있습니다.

path가 기존 일반 파일 인 경우 True 반환합니다. 이것은 심볼릭 링크를 따르므로 동일한 경로에 대해 islink()os.path.isfile 이 모두 참일 수 있습니다.

import os.path
os.path.isfile(fname) 

파일인지 확인해야합니다.

Python 3.4부터 pathlib 모듈 은 객체 지향 접근법을 제공합니다 (Python 2.7에서 pathlib2 로 백 포트 됨).

from pathlib import Path

my_file = Path("/path/to/file")
if my_file.is_file():
    # file exists

디렉토리를 확인하려면 다음을 수행하십시오.

if my_file.is_dir():
    # directory exists

Path 객체가 파일인지 디렉토리인지에 관계없이 존재하는지 여부를 확인하려면 exists() 사용 exists() .

if my_file.exists():
    # path exists

try 블록에서 resolve() 를 사용할 수도 있습니다.

try:
    my_abs_path = my_file.resolve()
except FileNotFoundError:
    # doesn't exist
else:
    # exists



파일 또는 디렉토리가 존재하는지 확인하십시오.

다음 세 가지 방법을 따를 수 있습니다.

참고 1 : os.path.isfile파일에만 사용됩니다.

import os.path
os.path.isfile(filename) # True if file exists
os.path.isfile(dirname) # False if directory exists

주 2 : os.path.exists파일과 디렉토리 모두에 사용됩니다 .

import os.path
os.path.exists(filename) # True if file exists
os.path.exists(dirname) #True if directory exists

pathlib.Path방법 (Python 3+에 포함됨, Python 2 용 pip로 설치 가능)

from pathlib import Path
Path(filename).exists()



try 문을 사용하지 않고 파일이 있는지 여부를 어떻게 확인합니까?

2016 년에도 여전히 파일이 존재하고 파일인지 확인하는 가장 쉬운 방법입니다.

import os
os.path.isfile('./file.txt')    # Returns True if exists, else False

isfile내부적으로 사용하는 단지 도우미 메서드 실제로 os.stat하고 stat.S_ISREG(mode)아래는. 이것은 os.stat파일, 디렉토리, 소켓, 버퍼 등에 대한 자세한 정보를 제공하는 하위 레벨 방법입니다. os.stat에 대한 자세한 내용은 여기

참고 : 그러나이 방법은 파일을 어떤 식 으로든 잠그지 않으므로 코드가 "사용 시간 확인 "( TOCTTOU ) 버그에 취약해질 수 있습니다 .

따라서 예외를 발생시키는 것은 프로그램에서 흐름 제어를위한 허용 가능한 Pythonic 접근 방식으로 간주됩니다. 그리고 if문장 ( 그냥 조언 ) 보다는 IOErrors가있는 누락 된 파일을 처리하는 것을 고려해야합니다 .




파이썬의 "OS"라이브러리를 사용할 수 있습니다 :

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



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

예외 발생은 프로그램에서 흐름 제어를위한 허용 가능한 Pythonic 접근 방식으로 간주됩니다. IOErrors가있는 누락 된 파일 처리를 고려하십시오. 이 상황에서 파일이 있지만 사용자에게 읽기 권한이없는 경우 IOError 예외가 발생합니다.

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




os.path.exists 함수가 있습니다.

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

이것은 파일과 디렉토리 모두에 대해 True 를 반환하지만 대신

os.path.isfile(file_path)

특정 파일인지 테스트합니다. 그것은 심볼릭 링크를 따른다.




2017 / 12 / 22 :

거의 모든 가능한 방법이 기존 답변 (예 : Python 3.4 특정 항목이 추가됨) (적어도 하나 이상)에 나열되었지만 모든 것을 그룹화하려고 시도합니다.

참고 : 내가 게시 할 파이썬 표준 라이브러리 코드의 모든 부분은 버전 3.5.3에 속합니다 (의사 인용문은 버전 3 에만 해당).

문제 성명서 :

  1. 확인 파일 ( arguable : 또한 폴더 ( "특수"파일)?) 존재
  2. try / except / else / finally 블록을 사용하지 마십시오.

가능한 해결책 :

  1. [파이썬] : os.path. 존재 ( 경로 ) (또한 약간 다른 행동에 대해 os.path.isfile , os.path.isdir , os.path.lexists 와 같은 다른 기능 패밀리 구성원을 확인하십시오)

    os.path.exists(path)
    

    path 가 기존 경로 또는 열려있는 파일 설명자를 참조하면 True 반환합니다. 깨진 심볼릭 링크에 대해 False 를 반환합니다. 일부 플랫폼에서는 경로가 실제로 존재하더라도 요청한 파일에서 os.stat() 을 실행하는 권한이 부여되지 않으면이 함수가 False 반환합니다.

    모두 좋지만, 임포트 트리를 따르는 경우 :

    • os.path - posixpath.py ( ntpath.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 는 프레임 스택에서 (적어도) 하나의 블록이 있습니다. 이것은 다른 기능 ( os.path.isfile 포함 )에도 적용됩니다.

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

    • 그것은 더 다루기 좋은 (그리고 더 많은 파이썬 ic) 경로를 다루는 방법 이지만
    • 후드 아래에서는 똑같은 일을합니다 ( pathlib.py , line ~ # 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 동작을 복제 할 것입니다 (이는 단지 목적을 설명하기위한 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을 사용하십시오 . suppress ( * exceptions ) - 예외 를 선택적으로 억제하기 위해 특별히 설계되었습니다.


    하지만, 그들은 try/except/else/finally 블록 위에있는 래퍼처럼 보일 것입니다. [Python] : with 은 다음 같이 나타냅니다 :

    이렇게하면 일반적인 try ... except ... finally 사용 패턴을 편리한 재사용을 위해 캡슐화 할 수 있습니다.

  3. 파일 시스템 순회 기능 (그리고 일치하는 항목에 대한 결과 검색)


    이러한 것들은 폴더에 대해 반복되므로 (대부분의 경우) 우리의 문제에는 비효율적입니다 (@ shadowRanger가 지적한 바와 같이 예외는 아닙니다. @ ShadowRanger가 지적한 바와 같이). 그래서 저는 그것들을 고집하지 않을 것입니다. 어떤 경우에는 파일 이름 처리가 필요할 수도 있습니다.

  4. [파이썬] : os. 행동이 os.path.exists 가깝게 접근하는 (실제로는 2 번째 인수 때문에 더 넓다. ) access ( 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 ICS가 아닙니다. 따라서 @AaronHall이 지적한 바에 따르면, 무엇을하고 있는지 알지 못한다면 그것을 사용하지 마십시오 :

    참고 : [파이썬]을 통해 원시 API를 호출 할 수도 있습니다 . 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입니다 ).
    • 파이썬 3파이썬 2 에서 동일한 코드가 작동하도록 _waccess를 사용 하고 있습니다 ( 유니 코드 관련 차이점에도 불구하고)
    • 이것은 매우 특정한 영역을 대상으로하지만 이전 답변에서는 언급되지 않았습니다.


    Lnx ( Ubtu (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 ()에 주어지면이 핸들은 프로그램 시작시로드 된 모든 공유 객체와 그 다음에 RTLD_GLOBAL 플래그로 dlopen ()에 의해로드 된 모든 공유 객체가 뒤 따르는 주 프로그램에서 심볼을 검색합니다.

      • 주 (현재) 프로그램 ( 파이썬 )은 libc에 링크되어 있으므로, 심볼 ( access 포함)이로드됩니다
      • main , Py_Main 및 (모든) 다른 함수를 사용할 수 있으므로주의해서 처리해야합니다. 그 (것)들을 부르는 것은 (현재 프로그램에) 비참한 효력이있을 수 있었다
      • msvcrt.dll 은 기본적으로 % PATH % 에있는 "% SystemRoot % \ System32" 에 있기 때문에 이것은 큰 문제는 아닙니다. 그러나 Win 에는 적용되지 않습니다. 추가 작업을 수행하고 Win 에서이 동작을 복제 (및 패치 제출)하고 싶었지만 [MSDN] : GetProcAddress 함수내 보낸 심볼을 "보았" 만하 므로 다른 사람이 기본 실행 파일의 함수를 __declspec(dllexport) (지구상에서 정규 사람이 그렇게하는 이유는 무엇입니까?), 메인 프로그램은로드 가능하지만 꽤 쓸모가 없습니다
  5. 파일 시스템 기능을 갖춘 타사 모듈을 설치하십시오.

    대부분 위의 방법 중 하나에 의존합니다 (약간의 사용자 지정이 필요할 수 있음).
    한 가지 예가 (다시 Win 특정) [GitHub] : Windows 용 Python (pywin32) Extensions , WINAPI를 통한 Python 래퍼입니다.

    그러나이 방법은 해결 방법과 비슷하기 때문에 여기서 멈추고 있습니다.

  6. 또 다른 (절름발이) 해결 방법 ( gainarie )은 sysadmin 접근법입니다 ( 파이썬 을 래퍼로 사용하여 쉘 명령을 실행합니다).

    • 승리 :

      (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
      
    • Lnx ( Ubtu ) :

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

결론 :

  • try / except / else / finally 블록을 사용하면 일련의 불쾌한 문제가 발생하는 것을 방지 할 수 있습니다. 생각할 수있는 반례는 성능입니다. 이러한 블록은 비용이 많이 들기 때문에 초당 수십만 번 실행되는 코드에 배치하지 마십시오 (그러나 대부분의 경우 디스크 액세스, 그것은 사실이 아닐 것이다).

최종 메모 :

  • 나는 그것을 최신으로 유지하려고 노력할 것입니다. 어떤 제안이라도 환영합니다. 나는 대답으로 올 수있는 유용한 것을 포함시킬 것입니다.



Brian의 제안을없이 작성할 수 있습니다 try:.

from contextlib import suppress

with suppress(IOError), open('filename'):
    process()

suppressPython 3.4의 일부입니다. 이전 버전에서는 신속하게 직접 작성을 할 수 있습니다.

from contextlib import contextmanager

@contextmanager
def suppress(*exceptions):
    try:
        yield
    except exceptions:
        pass



날짜 : 2017-12-04

가능한 모든 해결책이 다른 대답에 나열되어 있습니다.

파일이 존재 하는지를 확인하는 직관적이고 논쟁 할 수있는 방법은 다음과 같습니다.

import os
os.path.isfile('~/file.md')    # Returns True if exists, else False
additionaly check a dir
os.path.isdir('~/folder') # Returns True if the folder exists, else False
check either a dir or a file
os.path.exists('~/file')

참조 용 철저한 치트 시트를 만들었습니다.

#os.path methods in exhaustive cheatsheet
{'definition': ['dirname',
               'basename',
               'abspath',
               'relpath',
               'commonpath',
               'normpath',
               'realpath'],
'operation': ['split', 'splitdrive', 'splitext',
               'join', 'normcase'],
'compare': ['samefile', 'sameopenfile', 'samestat'],
'condition': ['isdir',
              'isfile',
              'exists',
              'lexists'
              'islink',
              'isabs',
              'ismount',],
 'expand': ['expanduser',
            'expandvars'],
 'stat': ['getatime', 'getctime', 'getmtime',
          'getsize']}



os.path.isfile() , os.path.isdir()os.path.exists() 하여 파일 및 폴더 테스트

"경로"가 유효한 경로라고 가정하면이 테이블은 파일 및 폴더에 대해 각 함수가 반환하는 내용을 보여줍니다.

또한 os.path.splitext() 를 사용하여 특정 유형의 파일인지 테스트하여 확장을 가져올 수 있습니다 (아직 모르는 경우).

>>> import os
>>> path = "path to a word document"
>>> os.path.isfile(path)
True
>>> os.path.splitext(path)[1] == ".docx" # test if the extension is .docx
True



또한 os.access():

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

이어서 R_OK, W_OKX_OK플래그 권한 (테스트 할 문서 ).




이것은 파일이 있는지를 확인하는 가장 간단한 방법입니다. 파일을 검사했을 때 존재했다고해서 파일을 열어야 할 때 파일이 존재한다는 것을 보장 하지는 않습니다.

import os
fname = "foo.txt"
if os.path.isfile(fname):
    print("file does exist at this time")
else:
    print("no such file exists at this time")



저는 약 10 년 동안 있었던 패키지의 저자이며,이 문제를 직접 해결하는 기능을 가지고 있습니다. 기본적으로 비 Windows 시스템에있는 경우 Popen액세스 하는 데 사용 됩니다 find. 그러나 Windows를 find사용하는 경우 효율적인 파일 시스템 워커를 사용하여 복제합니다 .

코드 자체는 try운영체제를 결정할 때를 제외하고 는 블록을 사용하지 않으므로 "Unix"스타일 find또는 손으로 작성해야 find합니다. 타이밍 테스트는 tryOS를 결정 하는 것이 더 빠르다 는 것을 보여 주었기 때문에 거기에서 하나를 사용했습니다 (그러나 아무데도 사용하지 않았습니다).

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

그리고 의사가 ...

>>> 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']

>>>

구현 방법은 다음과 같습니다. https://github.com/uqfoundation/pox/blob/89f90fb308f285ca7a62eabe2c38acb87e89dad9/pox/shutils.py#L190




2016 년 가장 좋은 방법은 여전히 os.path.isfile 사용하는 것입니다.

>>> os.path.isfile('/path/to/some/file.txt')

또는 파이썬 3에서는 pathlib 를 사용할 수 있습니다 :

import pathlib
path = pathlib.Path('/path/to/some/file.txt')
if path.is_file():
    ...



당신이 다른 목적을 위해 이미 NumPy와를 가져온 경우 다음과 같은 다른 라이브러리를 가져올 필요가 없습니다 pathlib, os, paths, 등

import numpy as np
np.DataSource().exists("path/to/your/file")

이것은 존재 여부에 따라 true 또는 false를 반환합니다.




os.access() 와 함께 os.path.isfile() 을 사용하십시오.

import os
import os.path

PATH='./file.txt'

if os.path.isfile(PATH) and os.access(PATH, os.R_OK):
    print "File exists and is readable"
else:
    print "Either the file is missing or not readable"



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 (directory or file) exists or not
os.path.isfile(path) # Returns whether the file exists or not



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 이상)을 사용하고 있다면 pip와 함께 pathlib를 설치할 수 있습니다.

# 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



try 문을 사용하지 않고 Python을 사용하여 파일이 있는지 여부를 어떻게 확인합니까?

이제는 Python 3.4부터 사용할 수 있으며 파일 이름으로 Path 객체를 가져 와서 인스턴스화하고 is_file 메소드를 확인합니다 (일반 파일을 가리키는 심볼릭 링크의 경우 True를 반환합니다).

>>> from pathlib import Path
>>> Path('/').is_file()
False
>>> Path('/initrd.img').is_file()
True
>>> Path('/doesnotexist').is_file()
False

Python 2를 사용하고 있다면 pypi, pathlib2 에서 pathlib 모듈을 백 포트하거나 os.path 모듈에서 isfile 을 확인할 수있다.

>>> import os
>>> os.path.isfile('/')
False
>>> os.path.isfile('/initrd.img')
True
>>> os.path.isfile('/doesnotexist')
False

이제 위의 내용은 아마도 실용적인 직접 답변 일 수도 있지만 경쟁하려는 상황에 따라 경쟁 조건이 발생할 수 있으며 기본 구현에는 try 사용되지만 Python에서는 모든 환경에서 try 사용합니다. 이행.

파이썬은 어디에서나 try 사용하기 때문에이를 사용하는 구현을 피할 이유가 없습니다.

그러나이 답변의 나머지 부분에서는 이러한주의 사항을 고려하려고합니다.

더 길고 훨씬 더 답답한 대답

Python 3.4부터 사용 가능하며 pathlib 새로운 Path 객체를 사용하십시오. .exists 는 디렉토리가 파일이 아니기 때문에 (파일이 유닉스라는 점을 제외하고는) 모든 디렉토리가 파일이 아니기 때문에 적절하지 않습니다.

>>> from pathlib import Path
>>> root = Path('/')
>>> root.exists()
True

그래서 우리는 is_file 을 사용할 필요가있다.

>>> root.is_file()
False

is_file 대한 도움말은 다음과 같습니다.

is_file(self)
    Whether this path is a regular file (also True for symlinks pointing
    to regular files).

이제 우리가 알고있는 파일을 파일로 만들어 보겠습니다.

>>> import tempfile
>>> file = tempfile.NamedTemporaryFile()
>>> filepathobj = Path(file.name)
>>> filepathobj.is_file()
True
>>> filepathobj.exists()
True

기본적으로 NamedTemporaryFile 은 닫힐 때 파일을 삭제합니다 (참조가 더 이상 존재하지 않으면 자동으로 닫힙니다).

>>> del file
>>> filepathobj.exists()
False
>>> filepathobj.is_file()
False

구현 을 파고 들면 is_filetry 사용한다는 것을 알 수있다.

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

경쟁 조건 : 우리가 시도하는 이유

우리는 경쟁 조건을 피하기 때문에 try 좋아합니다. try 를 사용하면 단순히 파일을 읽으려고 시도하고 거기에있을 것으로 예상하고, 그렇지 않을 경우 예외를 catch하고 대체 동작이 의미가있는 작업을 수행합니다.

파일을 읽으려고 시도하기 전에 파일이 있는지 확인하고 삭제하려고하면 다중 스레드 또는 프로세스를 사용하고 있거나 다른 프로그램이 해당 파일을 알고 삭제할 수 있습니다. 경쟁 조건은 그것이 존재하는지 확인하면 조건 (존재)이 변경되기 전에 열리기 때문에 경쟁 조건 이 존재합니다.

경쟁 조건은 프로그램을 실패하게 만들 수있는 매우 작은 창 때문에 디버그하기가 매우 어렵습니다.

그러나 이것이 당신의 동기라면, suppress 컨텍스트 관리자를 사용하여 try 문의 값을 얻을 수 있습니다 .

try 문없이 경쟁 조건을 피하십시오.

파이썬 3.4에서는 우리가 suppress 컨텍스트 관리자 (이전에는 ignore 컨텍스트 관리자)를 제공합니다.이 컨텍스트 관리자는 더 적은 수의 줄에서 의미 상으로는 똑같은 작업을 수행하고, 원래는 적어도 문법적으로 만 수행하면 try 문을 피할 수 있습니다.

from contextlib import suppress
from pathlib import Path

용법:

>>> with suppress(OSError), Path('doesnotexist').open() as f:
...     for line in f:
...         print(line)
... 
>>>
>>> with suppress(OSError):
...     Path('doesnotexist').unlink()
... 
>>> 

이전의 Pythons에서는 자신 만의 suppress 굴릴 수는 있었지만 try 하지 않고서는보다 자세한 정보를 얻을 수 있습니다. 나는 이것이 실제로 컨텍스트 관리자를 사용하기 때문에 파이썬 3.4 이전에 적용될 수있는 파이썬의 모든 레벨에서 사용하지 않는 유일한 대답 이라고 생각한다.

class suppress(object):
    def __init__(self, *exceptions):
        self.exceptions = exceptions
    def __enter__(self):
        return self
    def __exit__(self, exc_type, exc_value, traceback):
        if exc_type is not None:
            return issubclass(exc_type, self.exceptions)

아마 쉽게 시도 :

from contextlib import contextmanager

@contextmanager
def suppress(*exceptions):
    try:
        yield
    except exceptions:
        pass

"시도하지 말 것"을 요구하지 않는 다른 옵션 :

isfile

import os
os.path.isfile(path)

docs :

os.path.isfile(path)

path가 기존 일반 파일 인 경우 True를 반환합니다. 이것은 심볼릭 링크를 따르므로 동일한 경로에 대해 islink()isfile() 이 모두 참일 수 있습니다.

그러나이 함수의 source 를 살펴보면 실제로 try 문을 사용한다는 것을 알 수 있습니다.

# This follows symbolic links, so both islink() and isdir() can be true
# for the same path on systems that support symlinks
def isfile(path):
    """Test whether a path is a regular file"""
    try:
        st = os.stat(path)
    except os.error:
        return False
    return stat.S_ISREG(st.st_mode)
>>> OSError is os.error
True

모든 작업은 주어진 경로를 사용하여 통계를 얻을 수 있는지 여부를 확인하고 OSError 포착 한 다음 예외가 발생하지 않은 경우 파일인지 확인합니다.

파일을 가지고 무엇인가를하고자한다면, race-condition을 피하기 위해 try-except와 함께 직접 시도해 볼 것을 제안합니다 :

try:
    with open(path) as f:
        f.read()
except OSError:
    pass

os.access

유닉스에서 사용 가능하며 Windows는 os.access 이지만 플래그를 전달해야하므로 파일과 디렉토리를 구별하지 않습니다. 실제 호출하는 사용자가 상승 된 권한 환경에 액세스 할 수 있는지 테스트하는 데 더 많이 사용됩니다.

import os
os.access(path, os.F_OK)

또한 isfile 과 같은 경쟁 조건 문제로 어려움을 isfile . docs :

참고 : open ()을 사용하여 파일을 실제로 열기 전에 파일을 여는 권한이 있는지 확인하기 위해 access ()를 사용하면 보안 구멍이 생깁니다. 사용자가 파일을 확인하고 여는 사이의 짧은 시간 간격을 악용 할 수 있기 때문입니다. EAFP 기술을 사용하는 것이 바람직합니다. 예 :

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

더 낫다 :

try:
    fp = open("myfile")
except IOError as e:
    if e.errno == errno.EACCES:
        return "some default data"
    # Not a permission error.
    raise
else:
    with fp:
        return fp.read()

os.access 사용하지 마십시오. 위에 설명 된 상위 수준의 개체 및 기능보다 사용자 오류 가능성이 더 많은 저급 기능입니다.

다른 대답에 대한 비판 :

또 다른 대답은 os.access 에 대해 다음과 같이 말합니다.

개인적으로, 나는 후드 아래에서 원시 API ( "$ {PYTHON_SRC_DIR} /Modules/posixmodule.c"를 통해)를 호출하기 때문에이 코드를 선호하지만 가능한 사용자 오류에 대한 문을 열어 다른 변형과 비교해서 Python 코드가 아닙니다. :

이 답변은 비이용적이고 오류가 발생하지 않는 방법을 선호한다고 말합니다. 그것은 사용자가 그들을 이해하지 않고 낮은 수준의 API를 사용하도록 권장하는 것 같습니다.

또한 True 를 무조건적으로 돌려줌으로써 ( KeyboardInterruptSystemExit !를 포함한) 모든 예외가 자동으로 패스 할 수있게하는 컨텍스트 관리자를 생성합니다. 이것은 버그를 숨기는 좋은 방법입니다.

이것은 사용자가 빈약 한 관행을 채택하도록 유도하는 것으로 보인다.







디렉토리를 매개 변수로 사용하여 findfiles ()를 실행하면 그 안에있는 모든 파일의 목록을 반환합니다.

import os
def findfiles(directory):
    objects = os.listdir(directory)  # find all objects in a dir

    files = []
    for i in objects:  # check if very object in the folder ...
        if os.path.isfile(os.path.join(directory, i)):  # ... is a file.
            files.append(i)  # if yes, append it.
    return files






python file file-exists