파일이 기록될 디렉토리가 있는지 어떻게 확인하고, 없으면 Python을 사용하여 디렉토리를 생성합니까?
Python ≥ 3.5에서는 다음을 사용합니다 pathlib.Path.mkdir
.
from pathlib import Path
Path("/my/directory").mkdir(parents=True, exist_ok=True)
이전 버전의 Python의 경우에는 각각 작은 결함이 있는 좋은 품질의 두 가지 답변이 있으므로 이에 대해 설명하겠습니다.
시도 하고 생성 os.path.exists
을 고려 os.makedirs
하십시오.
import os
if not os.path.exists(directory):
os.makedirs(directory)
주석 및 다른 곳에서 언급했듯이 경합 조건이 있습니다. 디렉터리가 os.path.exists
와 os.makedirs
호출 사이에 생성 os.makedirs
되면 OSError
. 불행히도, 블랭킷 캐치 OSError
및 계속은 불충분한 권한, 전체 디스크 등과 같은 다른 요인으로 인한 디렉토리 생성 실패를 무시하므로 완벽한 방법은 아닙니다.
OSError
한 가지 옵션은 포함된 오류 코드 를 트래핑 하고 검사하는 것입니다( Python의 OSError에서 정보를 얻는 교차 플랫폼 방법 참조 ):
import os, errno
try:
os.makedirs(directory)
except OSError as e:
if e.errno != errno.EEXIST:
raise
또는 두 번째가 있을 수 os.path.exists
있지만 첫 번째 확인 후에 다른 사람이 디렉터리를 생성한 다음 두 번째 확인 전에 디렉터리를 제거했다고 가정해 보겠습니다. 우리는 여전히 속일 수 있습니다.
응용 프로그램에 따라 동시 작업의 위험은 파일 권한과 같은 다른 요인으로 인한 위험보다 많거나 적을 수 있습니다. 개발자는 구현을 선택하기 전에 개발 중인 특정 응용 프로그램과 예상 환경에 대해 더 많이 알아야 합니다.
최신 버전의 Python은 (3.3+에서) 노출을 통해 이 코드를 상당히 개선합니다 FileExistsError
.
try:
os.makedirs("path/to/directory")
except FileExistsError:
# directory already exists
pass
...그리고 키워드 인수를 os.makedirs
호출exist_ok
하도록 허용함으로써 (3.2 이상에서).
os.makedirs("path/to/directory", exist_ok=True) # succeeds even if directory exists.
파이썬 3.5 이상:
import pathlib
pathlib.Path('/my/directory').mkdir(parents=True, exist_ok=True)
pathlib.Path.mkdir
위에서 사용된 것처럼 재귀적으로 디렉토리를 생성하고 디렉토리가 이미 존재하는 경우 예외를 발생시키지 않습니다. 부모가 필요하지 않거나 생성되기를 원하는 경우 parents
인수를 건너뜁니다.
파이썬 3.2 이상:
사용 pathlib
:
가능하면 pathlib
이라는 이름의 현재 백포트 를 설치하십시오 pathlib2
. 이라는 이름의 유지 관리되지 않는 이전 백포트를 설치하지 마십시오 pathlib
. 다음으로, 위의 Python 3.5+ 섹션을 참조하고 동일하게 사용하십시오.
Python 3.4를 사용하는 경우 와 함께 제공되지만 pathlib
유용한 exist_ok
옵션이 없습니다. mkdir
백포트는 누락된 옵션이 포함된 보다 새롭고 우수한 구현을 제공하기 위한 것 입니다.
사용 os
:
import os
os.makedirs(path, exist_ok=True)
os.makedirs
위에서 사용된 것처럼 재귀적으로 디렉토리를 생성하고 디렉토리가 이미 존재하는 경우 예외를 발생시키지 않습니다. exist_ok
기본값은 Python 3.2 이상을 사용하는 경우에만 선택적 인수가 False
있습니다. 이 인수는 Python 2.x 2.7까지 존재하지 않습니다. 따라서 Python 2.7에서와 같이 수동 예외 처리가 필요하지 않습니다.
파이썬 2.7 이상:
사용 pathlib
:
가능하면 pathlib
이라는 이름의 현재 백포트 를 설치하십시오 pathlib2
. 이라는 이름의 유지 관리되지 않는 이전 백포트를 설치하지 마십시오 pathlib
. 다음으로, 위의 Python 3.5+ 섹션을 참조하고 동일하게 사용하십시오.
사용 os
:
import os
try:
os.makedirs(path)
except OSError:
if not os.path.isdir(path):
raise
순진한 솔루션은 먼저 를 사용 os.path.isdir
하고 os.makedirs
, 위의 솔루션은 두 작업의 순서를 반대로 합니다. 이렇게 하면 디렉터리를 만들려는 중복된 시도와 관련된 일반적인 경쟁 조건을 방지하고 디렉터리에서 파일을 명확하게 구분합니다.
예외를 캡처하고 사용하는 errno
것은 유용성이 제한적입니다 OSError: [Errno 17] File exists
. 즉 errno.EEXIST
, 파일과 디렉토리 모두에 대해 가 발생하기 때문입니다. 단순히 디렉토리가 존재하는지 확인하는 것이 더 안정적입니다.
대안:
mkpath
중첩된 디렉터리를 만들고 디렉터리가 이미 있는 경우 아무 작업도 수행하지 않습니다. 이것은 Python 2와 3 모두에서 작동합니다.
import distutils.dir_util
distutils.dir_util.mkpath(path)
버그 10948 에 따라 이 대안의 심각한 제한은 주어진 경로에 대해 파이썬 프로세스당 한 번만 작동한다는 것입니다. 즉, 디렉토리를 생성하는 데 사용하고 Python 내부 또는 외부에서 디렉토리를 삭제한 다음 mkpath
다시 사용하여 동일한 디렉토리를 다시 mkpath
생성하면 이전에 디렉토리를 생성한 유효하지 않은 캐시 정보를 자동으로 사용하고 실제로 디렉토리를 다시 만드십시오. 대조적으로, os.makedirs
그러한 캐시에 의존하지 않습니다. 이 제한은 일부 응용 프로그램에 적합할 수 있습니다.
디렉토리의 모드 와 관련하여 신경이 쓰이는 경우 문서를 참조하십시오.
try 예외를 사용하고 errno 모듈의 올바른 오류 코드는 경쟁 조건을 제거하고 플랫폼 간입니다.
import os
import errno
def make_sure_path_exists(path):
try:
os.makedirs(path)
except OSError as exception:
if exception.errno != errno.EEXIST:
raise
즉, 디렉토리를 생성하려고 시도하지만 디렉토리가 이미 존재하는 경우 오류를 무시합니다. 반면에 다른 모든 오류가 보고됩니다. 예를 들어 dir 'a'를 미리 만들고 모든 권한을 제거하면 (Permission denied, error 13)가 발생합니다 OSError
.errno.EACCES
'파이썬' 카테고리의 다른 글
[Python] 목록 목록에서 플랫 목록을 만드는 방법은 무엇입니까? (0) | 2022.07.31 |
---|---|
[Python] 'for' 루프에서 인덱스 액세스 (0) | 2022.07.31 |
[Python] 어떻게 프로그램을 실행하거나 시스템 명령을 호출합니까? (0) | 2022.07.31 |
[Python] 단일 표현식에서 두 개의 사전을 병합하려면 어떻게 해야 합니까? (0) | 2022.07.31 |
[Python] 파일이 예외 없이 존재하는지 어떻게 확인합니까? (0) | 2022.07.31 |