try
명령문 을 사용하지 않고 파일이 존재하는지 여부를 어떻게 확인 합니까?
답변
당신이 확인하는 이유가 당신과 같은 것을 할 수 있다면 if file_exists: open_it()
그것을 try
여는 시도 주위 를 사용하는 것이 더 안전 합니다. 확인 후 파일을 열면 파일이 삭제되거나 이동 될 때 또는 파일을 열 때와 열 때 사이에 무언가 위험이 있습니다.
파일을 즉시 열지 않을 경우 사용할 수 있습니다 os.path.isfile
True
경로가 기존 일반 파일 인 경우 반환 합니다. 이는 심볼릭 링크를 따르므로 동일한 경로에 대해 islink () 및 isfile () 이 모두 참일 수 있습니다.
import os.path
os.path.isfile(fname)
파일인지 확인해야하는 경우
Python 3.4부터 pathlib
모듈 은 객체 지향 접근 방식을 제공합니다 ( pathlib2
Python 2.7에서 백 포트 됨 ).
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()
다음을 사용하십시오 .
if my_file.exists():
# path exists
블록 resolve(strict=True)
에서 사용할 수도 있습니다 try
.
try:
my_abs_path = my_file.resolve(strict=True)
except FileNotFoundError:
# doesn't exist
else:
# exists
답변
당신은 os.path.exists
기능이 있습니다 :
import os.path
os.path.exists(file_path)
이것은 True
파일과 디렉토리 모두에 대해 반환 하지만 대신 사용할 수 있습니다
os.path.isfile(file_path)
구체적으로 파일인지 테스트합니다. 심볼릭 링크를 따릅니다.
답변
달리 isfile()
, exists()
반환 True
디렉토리에. 당신은 단지 일반 파일이나 또한 디렉토리를 원하는 경우에 따라 그래서, 당신은 사용할 것 isfile()
나 exists()
. 다음은 간단한 REPL 출력입니다.
>>> os.path.isfile("/etc/password.txt")
True
>>> os.path.isfile("/etc")
False
>>> os.path.isfile("/does/not/exist")
False
>>> os.path.exists("/etc/password.txt")
True
>>> os.path.exists("/etc")
True
>>> os.path.exists("/does/not/exist")
False
답변
import os.path
if os.path.isfile(filepath):
답변
os.path.isfile()
함께 사용 os.access()
:
import os
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")
답변
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 관련 항목이 추가됨) 에 나열되어 있지만 모든 것을 함께 그룹화하려고 시도합니다.
참고 : 게시 할 모든 Python 표준 라이브러리 코드는 버전 3.5.3에 속합니다 .
문제 진술 :
- 파일 점검 ( 논쟁의 여지 : 폴더 ( “특별한”파일)?) 존재
- try / except / else / finally 블록을 사용하지 마십시오
가능한 해결책 :
-
[파이썬 3] : os.path. 존재 ( 경로 ) (또한 같은 다른 기능 가족 구성원을 확인
os.path.isfile
,os.path.isdir
,os.path.lexists
약간 다른 행동에 대한)os.path.exists(path)
path 가 기존 경로 또는 열린 파일 설명자를 참조
True
하면 반환 합니다 . 깨진 심볼릭 링크를 반환 합니다. 일부 플랫폼에서이 함수는 경로가 실제로 존재 하더라도 요청 된 파일에서 os.stat () 를 실행할 수 있는 권한이 부여되지 않은 경우 반환 될 수 있습니다.False
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
-
[Python 3] : os 주변 의 시도 / 제외 블록 입니다. stat ( path, *, dir_fd = None, follow_symlinks = True ) . 따라서 코드는 무료 / 시도를 제외하고 시도 하지만 프레임 스택에는 (적어도) 그러한 블록이 하나 이상 있습니다. 이는 다른 기능 (을 포함한
os.path.isfile
) 에도 적용됩니다 .- 경로를 다루는 더 환상적인 (그리고 더 많은 파이썬 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
-
-
[Python 3] : 명령문 컨텍스트 관리자 사용 . 어느 한 쪽:
-
하나를 만듭니다 :
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 ...)
-
그리고 사용법-나는
os.path.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 3] : contextlib를 사용하십시오 . suppress ( * exceptions ) – 예외 를 선택적으로 억제하기 위해 특별히 고안되었습니다.
그러나, 그들은 이상 래퍼 것으로 보인다 시도 / 제외 / 다른 / 마지막 블록으로 [파이썬 3] : 사진 에 문 상태 :
-
-
파일 시스템 탐색 기능 (및 일치하는 항목에 대한 결과 검색)
-
[파이썬 3] : os. 은 listDir ( 경로 = ‘.’ ) (또는 [파이썬 3]. OS 위해 scandir ( ‘.’= 패스 ) 에 파이썬 V 3.5 +, 백 포트 : [PyPI] 위해 scandir )
-
후드 아래에서 다음을 모두 사용하십시오.
- Nix : [man7] : OPENDIR (3) / [man7] : READDIR (3) / [man7] : CLOSEDIR (3)
- 승리 : [MS.Docs] : FindFirstFileW 함수 / [MS.Docs] : FindNextFileW 함수 / [MS.Docs] : FindClose 함수
[GitHub] 를 통해 : python / cpython-(마스터) cpython / Modules / posixmodule.c
os.DirEntry 객체는 디렉토리를 스캔 할 때 운영 체제에서 정보를 제공하면 os.DirEntry 객체가이 정보를 노출 하므로 listdir () 대신 scandir ()을 사용하면 파일 유형 또는 파일 속성 정보가 필요한 코드의 성능이 크게 향상 될 수 있습니다 . 모든 os.DirEntry 메소드는 시스템 호출을 수행 할 수 있지만 is_dir () 및 is_file ()은 일반적으로 기호 링크에 대한 시스템 호출 만 필요합니다. os.DirEntry.stat ()는 항상 Unix에서 시스템 호출이 필요하지만 Windows에서는 기호 링크에 대한 호출 만 필요합니다.
-
- [파이썬 3] : os. 도보 ( top, topdown = True, onerror = None, followlinks = False )
- 사용 가능
os.listdir
( 사용os.scandir
가능한 경우)
- 사용 가능
- [파이썬 3] : glob. iglob ( 경로, *, = 재귀 거짓 ) (또는 그 이전 :
glob.glob
)- 순회 함수 자체는 아니지만 (적어도 경우에 따라)
os.listdir
- 순회 함수 자체는 아니지만 (적어도 경우에 따라)
그들은 우리의 문제에 대한 비효율적이다 (대부분의 경우) 폴더를 통해 이러한 반복 할 때문에 (비 와일드 카드 같은 예외가 있습니다 글로브의 내가 그들 주장하지 않을거야, 그래서 – @ShadowRanger는 지적 빙). 경우에 따라 파일 이름 처리가 필요할 수 있습니다.
-
-
[파이썬 3] : os. access ( path, mode, *, dir_fd = None, effective_ids = False, follow_symlinks = True ) 동작이 가까운
os.path.exists
(실제로는 주로 두 번째 인수 때문에 더 넓 습니다 )- doc 상태에 따라 사용자 권한으로 파일 “visibility”가 제한 될 수 있습니다.
… 호출 사용자에게 지정된 path 액세스 권한이 있는지 테스트하십시오 . 경로가 있는지 테스트하려면 mode 는 F_OK 여야합니다 .
os.access("/tmp", os.F_OK)
나는 또한 작업 때문에 C , 후드, 그것을 호출하기 때문에 나뿐만 아니라이 방법을 사용하는 네이티브 API 의 (통해, 다시 “$ {PYTHON_SRC_DIR} /Modules/posixmodule.c” )뿐만 아니라 수에 대한 게이트 열립니다 사용자 errors 이며 다른 변형 만큼 Python ic 이 아닙니다 . 따라서 @AaronHall이 올바르게 지적했듯이 수행중인 작업을 모르는 경우 사용하지 마십시오.
- Nix : [man7] : ACCESS (2) (!!! 사용법으로 인해 발생할 수 있는 보안 허점에 주의하십시오 !!!)
- 승리 : [MS.Docs] : GetFileAttributesW 함수
참고 : [Python 3]을 통해 네이티브 API를 호출 할 수도 있습니다 . ctypes -Python의 외부 함수 라이브러리 이지만 대부분의 경우 더 복잡합니다.
( Win 관련) : vcruntime * ( msvcr * ) .dll 에서 [MS.Docs] : _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.notexist", os.F_OK) -1
참고 사항 :
- 좋은 습관
os.F_OK
은 아니지만 전화에 사용하고 있지만 명확성을 위해 사용됩니다 (값은 0 ) - 내가 사용하고 _waccess을 에 동일한 코드가 작동하도록 Python3 및 Python2 (에도 불구하고 유니 코드가 그들 사이의 차이를 관련)
- 이것은 매우 구체적인 영역을 목표로하지만 이전 답변에서는 언급되지 않았습니다.
LNX ( Ubtu (16 64) 뿐만 아니라) 상대 :
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"/tmp.notexist", os.F_OK) -1
참고 사항 :
-
대신 시스템에 따라 다를 수있는 libc 의 경로 ( “/lib/x86_64-linux-gnu/libc.so.6” )를 하드 코딩하는 대신 CDLL 생성자에 None (또는 빈 문자열)을 전달할 수 있습니다. ( ). [man7] 에 따르면 : DLOPEN (3) :
ctypes.CDLL(None).access(b"/tmp", os.F_OK)
경우 파일 이름이 NULL이고, 다음 반환 된 핸들은 메인 프로그램입니다. dlsym ()이 주어지면 이 핸들은 기본 프로그램에서 기호를 찾은 다음 프로그램 시작시로드 된 모든 공유 객체 와 RTDL_GLOBAL 플래그 로 dlopen ()에 의해로드 된 모든 공유 객체 를 검색합니다 .
- 메인 (현재) 프로그램 ( python )은 libc에 연결되어 있으므로 심볼 ( 액세스 포함 ) 이로 드됩니다
- main , Py_Main 및 기타 기능과 같은 기능을 사용할 수 있으므로주의해서 다루어야 합니다. 그것들을 호출하면 비참한 영향을 줄 수 있습니다 (현재 프로그램에서)
- 이것은 또한 적용되지 않습니다 승 (하지만 이후 즉, 같은 큰 문제가 아니다 MSVCRT.DLL가 에 위치한 “% SYSTEMROOT % \ SYSTEM32” 에 % 경로 % 기본적으로). 더 나아가서 Win 에서이 동작을 복제 하고 패치를 제출하고 싶었지만 , [MS.Docs] : GetProcAddress 함수 는 내 보낸 심볼 만 “보여” , 누군가가 주 실행 파일에서 함수를 선언하지 않는 한 로
__declspec(dllexport)
(지구에있는 이유는 일반 사람이 그렇게 할 것?)는 메인 프로그램은로드 할 수 있지만, 거의 사용할 수 없습니다
- doc 상태에 따라 사용자 권한으로 파일 “visibility”가 제한 될 수 있습니다.
-
파일 시스템 기능이있는 일부 타사 모듈 설치
대부분 위의 방법 중 하나에 의존 할 것입니다 (약간의 사용자 정의가있을 수 있음).
하나의 예는 (다시 Win에 따라) [GitHub] : mhammond / pywin32-Windows 용 Python (pywin32) Extensions 는 WINAPI 의 Python 래퍼 입니다.그러나 이것은 해결 방법과 비슷하기 때문에 여기서 멈 춥니 다.
-
또 다른 (불충분 한) 해결 방법 ( gainarie )은 sysadmin 접근 방식입니다 ( 파이썬 을 래퍼로 사용하여 쉘 명령 실행)
-
승리 :
(py35x64_test) e:\Work\Dev\StackOverflow\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\StackOverflow\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
-
결론 :
- 수행 사용 시도 / 제외시켰다 / 다른 / 마침내 그들은 당신이 불쾌한 일련의 문제로 실행되지 않도록 할 수 있기 때문에, 블록. 제가 생각할 수있는 반례는 성능입니다. 이러한 블록은 비용이 많이 들기 때문에 초당 수십만 번 실행되도록 코드에 배치하지 마십시오 (그러나 대부분의 경우 디스크 액세스가 필요합니다. 그렇지 않습니다).
최종 메모 :
- 나는 그것을 최신 상태로 유지하려고 노력할 것입니다, 어떤 제안이라도 환영합니다, 나는 대답에 올 수있는 유용한 것을 통합 할 것입니다