[python] 파일이 있는지 확인하는 방법?


Answers

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

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

이것은 파일과 디렉토리 모두에 대해 True 를 반환하지만 os.path.isfile 을 사용하여 파일이 구체적인지 여부를 테스트 할 수 있습니다. 그것은 심볼릭 링크를 따른다.

Question

try 문을 사용하지 않고 파일이 존재하는지 여부를 확인하는 방법은 무엇입니까?




import os.path

if os.path.isfile(filepath):



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




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




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



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 / 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
#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 사용하십시오.




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

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

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




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

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

최종 메모 :

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



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



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.




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.




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



Related



Tags

python python   file