중첩 디렉토리를 안전하게 만드는 방법은 무엇입니까?


4244

파일을 작성할 디렉토리가 존재하는지 여부를 확인하고 그렇지 않은 경우 Python을 사용하여 디렉토리를 작성하는 가장 우아한 방법은 무엇입니까? 내가 시도한 것은 다음과 같습니다.

import os

file_path = "/my/directory/filename.txt"
directory = os.path.dirname(file_path)

try:
    os.stat(directory)
except:
    os.mkdir(directory)       

f = file(filename)

어떻게 든, 나는 놓쳤다 os.path.exists(kanja, Blair와 Douglas에게 감사한다). 이것이 내가 지금 가진 것입니다.

def ensure_dir(file_path):
    directory = os.path.dirname(file_path)
    if not os.path.exists(directory):
        os.makedirs(directory)

"open"에 대한 플래그가 있습니까? 자동으로 발생합니까?


27
일반적으로 파일 이름에 디렉토리가없는 경우를 고려해야합니다. 내 컴퓨터에서 dirname ( 'foo.txt')은 존재하지 않아 makedirs ()가 실패하게하는 ''을 제공합니다.
브라이언 호킨스

11
파이썬 2.7 os.path.mkdir은 존재하지 않습니다. 그것은이다 os.mkdir.
drevicko

6
경로가 존재하는 경우 디렉토리가 아닌 일반 파일이나 다른 객체가 아닌지 확인해야 할뿐만 아니라 (많은 답변 확인) 쓰기 가능한지 확인해야합니다 (이를 확인한 답변을 찾지 못했습니다)
miracle173

9
파일 경로 string의 부모 디렉토리를 만들기 위해 여기에 온 경우 p여기에 내 코드 스 니펫이 있습니다.os.makedirs(p[:p.rindex(os.path.sep)], exist_ok=True)
Thamme Gowda

답변:


5185

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.existsos.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 FileExistsError은 (3.3 이상에서) 노출 함으로써이 코드를 상당히 개선합니다 ...

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.

5
경쟁 조건은 좋은 점이지만 stackoverflow.com/questions/273192/#273208 의 접근 방식 은 디렉토리 작성 실패를 숨길 것입니다. 투표에 나쁘게 생각하지 마십시오. 답이 마음에 들지 않습니다. 투표권이 있습니다.
블레어 콘래드

27
os.path.exists ()는 무료가 아닙니다. 일반적인 경우 디렉토리가있을 경우 예외로 처리하지 않아야합니다. 즉, 파일을 열고 파일에 쓰고 OSError 예외를 포착하고 errno를 기반으로 makedir ()을 수행 한 후 다시 시도하거나 다시 시도하십시오. 로컬 메서드로 쓰기를 래핑하지 않으면 코드 중복이 발생합니다.
Andrew

22
os.path.existsTrue파일을 반환 합니다. 이 문제를 해결하기 위해 답변을 게시했습니다.
Acumenus

13
여기에 다른 답변에 대한 주석가가 언급했듯이, exists_ok매개 변수 os.makedirs()는 Python 3.2 이후로 경로의 기존 존재를 처리하는 방법을 다루는 데 사용할 수 있습니다.
Bobble

6
os.mkdirs()경로 구분 기호가 실수로 빠졌을 때 의도하지 않은 폴더를 만들 수 있으며 현재 폴더가 예상과 다른 경우 경로 요소에 경로 구분 기호가 포함됩니다. os.mkdir()이 버그 를 사용 하면 예외가 발생하여 해당 버그가 있음을 경고합니다.
drevicko

1241

파이썬 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_okPython 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 existserrno.EEXIST

대안 :

mkpath중첩 된 디렉토리를 작성하고 디렉토리가 이미 존재하면 아무 것도 수행하지 않습니다. 이것은 Python 2와 3에서 모두 작동합니다.

import distutils.dir_util
distutils.dir_util.mkpath(path)

버그 10948 당 ,이 대안의 심각한 제한은 주어진 경로에 대해 파이썬 프로세스 당 한 번만 작동한다는 것입니다. 즉, 디렉토리를 생성하기 위해 디렉토리를 사용하는 경우 Python 내부 또는 외부에서 디렉토리를 삭제 한 다음 mkpath다시 사용 하여 동일한 디렉토리를 다시 mkpath생성하고 이전에 디렉토리를 생성 한 잘못된 캐시 된 정보를 자동으로 사용합니다. 실제로 디렉토리를 다시 만드십시오. 대조적으로, os.makedirs그러한 캐시에 의존하지 않습니다. 일부 응용 프로그램에서는이 제한이 적용됩니다.


디렉토리 모드 와 관련하여 관심이있는 경우 문서를 참조하십시오.


13
이 답변은 내가 말할 수있는 한 거의 모든 특별한 경우를 다룹니다. 디렉토리가 거의 항상 존재할 것으로 예상하고 예외를 피할 수 있기 때문에 이것을 "os.path.isdir ()가 아닌 경우"에 래핑 할 계획입니다.
Charles L.

5
@CharlesL. 이유가 성능 인 경우 예외는 검사의 디스크 IO보다 저렴할 수 있습니다.
jpmc26

1
@ jpmc26 그러나 makedirs는 OSError를 던질 때만 확인할 때 추가 통계, umask, lstat를 수행합니다.
kwarunek

4
이것은 잠재적 인 FS 레이스 컨디션을 소개하기 때문에 오답입니다. Aaron Hall의 답변을 참조하십시오.
sleepycal

4
@sleepycal이 말했듯이 이것은 허용되는 답변과 비슷한 경쟁 조건으로 고통받습니다. 오류 발생과 os.path.isdir다른 사람 확인 사이 에 폴더가 삭제되면 해당 폴더가 존재하는 잘못되고 오래된 오래된 혼란스러운 오류가 발생합니다.
farmir

604

errno 모듈의 try except 및 올바른 오류 코드를 사용하면 경쟁 조건이 제거되고 크로스 플랫폼이 있습니다.

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'를 작성하고 모든 권한을 제거하면 (권한 거부, 오류 13) OSError과 함께 발생 errno.EACCES합니다.


24
허용되는 답변은 경쟁 조건이 있기 때문에 실제로 위험합니다. 그러나 경쟁 조건을 알지 못하거나 그것이 적용되지 않을 것이라고 생각되면 첫 번째 선택이 될 것입니다.
Heikki Toivonen

15
exception.errno != errno.EEXIST경로가 존재하지만 파일과 같은 비 디렉토리 오브젝트 인 경우를 실수로 무시하는 경우 에만 예외를 발생 시킵니다. 경로가 디렉토리가 아닌 오브젝트 인 경우 예외를 발생시켜야합니다.
Acumenus

178
위 코드는os.makedirs(path,exist_ok=True)
Navin

58
@Navin이 exist_ok파라미터는 Python 3.2에서 도입되었습니다. Python 2.x에는 없습니다. 나는 그것을 내 대답에 포함시킬 것이다.
Acumenus

26
@HeikkiToivonen 기술적으로, 다른 프로그램이 프로그램과 동시에 디렉토리와 파일을 수정하는 경우 전체 프로그램은 하나의 거대한 경쟁 조건입니다. 코드에서 디렉토리를 작성한 후 파일을 실제로 넣기 전에 다른 프로그램이이 디렉토리를 삭제하지 못하게하려면 어떻게해야합니까?
jpmc26

102

개인적으로 os.path.isdir()대신 테스트에 사용 하는 것이 좋습니다 os.path.exists().

>>> os.path.exists('/tmp/dirname')
True
>>> os.path.exists('/tmp/dirname/filename.etc')
True
>>> os.path.isdir('/tmp/dirname/filename.etc')
False
>>> os.path.isdir('/tmp/fakedirname')
False

당신이 가지고 있다면:

>>> dir = raw_input(":: ")

그리고 어리석은 사용자 입력 :

:: /tmp/dirname/filename.etc

...로 테스트하면 filename.etc인수를 전달할 때 이름이 지정된 디렉토리로 끝납니다 .os.makedirs()os.path.exists()


8
'isdir'만 사용하는 경우 디렉토리를 만들려고 할 때 여전히 같은 문제가 발생하지 않으며 동일한 이름의 파일이 이미 존재합니까?
MrWonderful

3
@MrWonderful 기존 파일 위에 디렉토리를 만들 때 발생하는 예외는 호출자에게 문제를 올바르게 반영합니다.
Damian Yerrick

79

점검 os.makedirs: (전체 경로가 존재하는지 확인하십시오.)
디렉토리가 존재할 수있는 사실을 처리하려면 catch하십시오 OSError. ( exist_okis False(기본값) 인 OSError경우 대상 디렉토리가 이미 존재하면 ) 가 발생합니다.

import os
try:
    os.makedirs('./path/to/somewhere')
except OSError:
    pass

19
try / except를 사용하면 디렉토리가 존재하지 않지만 어떤 이유로 든 디렉토리를 만들 수없는 경우 디렉토리 생성시 오류를 숨길 수 있습니다.
Blair Conrad

3
OSError경로가 기존 파일 또는 디렉토리 인 경우 여기에서 발생합니다. 이 문제를 해결하기 위해 답변을 게시했습니다.
Acumenus

4
여기가 반쯤입니다. OSError무시하기로 결정하기 전에 하위 오류 조건을 확인해야 합니다. stackoverflow.com/a/5032238/763269를 참조하십시오 .
Chris Johnson

71

파이썬 3.5부터 pathlib.Path.mkdirexist_ok플래그를 :

from pathlib import Path
path = Path('/my/directory/filename.txt')
path.parent.mkdir(parents=True, exist_ok=True) 
# path.parent ~ os.path.dirname(path)

이는 재귀 적으로 디렉토리를 작성하며 디렉토리가 이미 존재하는 경우 예외를 발생시키지 않습니다.

( 파이썬 3.2에서 시작 os.makedirs하는 exist_ok플래그 가있는 것처럼 os.makedirs(path, exist_ok=True))


46

이 상황의 특성에 대한 통찰력

특정 경로에 특정 파일을 제공하고 파일 경로에서 디렉토리를 가져옵니다. 그런 다음 디렉토리가 있는지 확인한 후 읽을 파일을 열려고 시도하십시오. 이 코드에 주석을 달려면

filename = "/my/directory/filename.txt"
dir = os.path.dirname(filename)

내장 함수 덮어 쓰기를 피하고 싶습니다 dir. 또한, filepath아마도 아마도 아마도 fullfilepath더 나은 의미 론적 이름 filename이므로 아마도 더 잘 쓰여질 것입니다 :

import os
filepath = '/my/directory/filename.txt'
directory = os.path.dirname(filepath)

최종 목표는 쓰기를 들어, 처음에이 파일을 열 수 상태,하지만 당신은 본질적으로의 파일을 열어이 같은 (코드 기준)이 목표에 접근하고 읽기 :

if not os.path.exists(directory):
    os.makedirs(directory)
f = file(filename)

독서를위한 오프닝 가정

거기에 있고 읽을 수있는 파일의 디렉토리를 만드는 이유는 무엇입니까?

파일을 열어보십시오.

with open(filepath) as my_file:
    do_stuff(my_file)

디렉토리 또는 파일이 없으면 IOError관련 오류 번호 errno.ENOENT가 나타납니다. 플랫폼에 관계없이 올바른 오류 번호를 가리 킵니다. 원하는 경우 다음과 같이 잡을 수 있습니다.

import errno
try:
    with open(filepath) as my_file:
        do_stuff(my_file)
except IOError as error:
    if error.errno == errno.ENOENT:
        print 'ignoring error because directory or file is not there'
    else:
        raise

우리가 글쓰기를 시작한다고 가정

이다 아마 당신이 원하는 것입니다.

이 경우 경쟁 조건이 없을 수 있습니다. 따라서 그대로 작업을 수행하지만 쓰기를 위해서는 w모드 로 열어야 합니다 (또는 a추가해야 함). 컨텍스트 관리자를 사용하여 파일을 여는 것도 Python 모범 사례입니다.

import os
if not os.path.exists(directory):
    os.makedirs(directory)
with open(filepath, 'w') as my_file:
    do_stuff(my_file)

그러나 모든 데이터를 동일한 디렉토리에 넣으려고 시도하는 여러 Python 프로세스가 있다고 가정하십시오. 그런 다음 디렉토리 작성에 대한 경합이있을 수 있습니다. 이 경우에는 makedirs호출을 try-except 블록 으로 감싸는 것이 가장 좋습니다 .

import os
import errno
if not os.path.exists(directory):
    try:
        os.makedirs(directory)
    except OSError as error:
        if error.errno != errno.EEXIST:
            raise
with open(filepath, 'w') as my_file:
    do_stuff(my_file)

34

os.path.exists기능을 사용해보십시오

if not os.path.exists(dir):
    os.mkdir(dir)

3
질문에 대해 언급하려고했지만 os.mkdir을 의미합니까? 내 파이썬 (2.5.2) ... 더 os.path.mkdir이 없습니다
블레어 콘라드에게

1
방법이 없습니다 os.path.mkdir(). os.path 모듈 은 경로 이름에 유용한 기능을 구현합니다 .
S. Serge

31

나는 다음을 내려 놓았다. 그러나 완전히 바보는 아닙니다.

import os

dirname = 'create/me'

try:
    os.makedirs(dirname)
except OSError:
    if os.path.exists(dirname):
        # We are nearly safe
        pass
    else:
        # There was an error on creation, so make sure we know about it
        raise

내가 말했듯이, 우리는 디렉토리를 만들지 못할 가능성이 있고 그 기간 동안 다른 프로세스를 만들 수 있기 때문에 이것이 결코 바보가 아닙니다.



두 가지 문제 : (1) 검사를 결정하기 전에 OSError의 하위 오류 상태를 확인해야합니다-stackoverflow.com/a/5032238/763269를 os.path.exists참조하십시오. (2) 성공 os.path.exists이 디렉토리가 존재한다는 것을 의미하지는 않습니다. 존재-파일, 심볼릭 링크 또는 다른 파일 시스템 객체 일 수 있습니다.
Chris Johnson

24

디렉토리가 존재하는지 확인하고 필요한 경우 작성 하시겠습니까?

이에 대한 직접적인 대답은 다른 사용자 나 프로세스가 디렉토리를 망칠 것으로 예상하지 않는 간단한 상황을 가정 한 것입니다.

if not os.path.exists(d):
    os.makedirs(d)

또는 디렉토리를 만들 때 경쟁 조건이 적용되는 경우 (예 : 경로를 확인한 후 다른 항목이 이미 만든 경우) 다음을 수행하십시오.

import errno
try:
    os.makedirs(d)
except OSError as exception:
    if exception.errno != errno.EEXIST:
        raise

그러나 아마도 더 나은 접근 방식은 다음을 통해 임시 디렉토리를 사용하여 자원 경합 문제를 회피하는 것입니다. tempfile .

import tempfile

d = tempfile.mkdtemp()

온라인 문서의 필수 사항은 다음과 같습니다.

mkdtemp(suffix='', prefix='tmp', dir=None)
    User-callable function to create and return a unique temporary
    directory.  The return value is the pathname of the directory.

    The directory is readable, writable, and searchable only by the
    creating user.

    Caller is responsible for deleting the directory when done with it.

Python 3.5의 새로운 기능 : pathlib.Pathexist_ok

새로운 것이있다 Path경로와 함께 사용하려는 많은 메소드 객체 (3.4 현재)가 있습니다.mkdir 있습니다.

상황에 따라 스크립트를 사용하여 주간 담당자를 추적하고 있습니다. 다음은 동일한 데이터에 대해 하루에 두 번 이상 스택 오버플로를 피할 수있게하는 스크립트의 관련 코드 부분입니다.

먼저 관련 수입품 :

from pathlib import Path
import tempfile

우리는 os.path.join지금 처리 할 필요가 없습니다 /.

directory = Path(tempfile.gettempdir()) / 'sodata'

그런 다음 디렉토리가 dem 등적으로 있는지 확인하십시오- exist_ok인수는 Python 3.5에 표시됩니다.

directory.mkdir(exist_ok=True)

문서 의 관련 부분은 다음과 같습니다 .

경우 exist_ok사실, FileExistsError예외는 같은 (동일한 동작을 무시됩니다POSIX mkdir -p 명령),하지만 마지막 경로 구성 요소가 기존 디렉토리가 아닌 파일이 아닌 경우에만 가능합니다.

여기에 약간의 스크립트가 있습니다. 제 경우에는 경쟁 조건이 아니며 디렉토리 (또는 포함 된 파일)가있을 것으로 예상되는 프로세스가 하나 뿐이며 제거하려는 것이 없습니다. 디렉토리.

todays_file = directory / str(datetime.datetime.utcnow().date())
if todays_file.exists():
    logger.info("todays_file exists: " + str(todays_file))
    df = pd.read_json(str(todays_file))

Path 물체를 강제로 strstr경로를 사용할 수있는 다른 API가 먼저 합니다.

아마도 추상 기본 클래스 인 인스턴스를 허용하도록 Pandas를 업데이트해야합니다 os.PathLike.


20

Python 3.4에서는 새로운 pathlib모듈을 사용할 수도 있습니다 .

from pathlib import Path
path = Path("/my/directory/filename.txt")
try:
    if not path.parent.exists():
        path.parent.mkdir(parents=True)
except OSError:
    # handle error; you can also catch specific errors like
    # FileExistsError and so on.

@JanuszSkonieczny의 pypi.python.org/pypi/pathlib2은 새로운 백 포트입니다. 오래된 것은 유지되지 않습니다.
Acumenus

readme의 첫 번째 줄에 언급 된 바와 같이; P. 그러나 이전 백 포트는 여전히 여기에 대한 답변에 유효합니다. 그리고 명명 두통이 없습니다. 왜, 언제 그리고 언제 pathlib어디 pathlib2에서 새로운 사용자 를 사용할지 설명 할 필요가 없으며 , 여기 프로가 지원 중단을 알아낼 것이라고 생각합니다.)
Janusz Skonieczny

13

관련 파이썬 문서 의 사용 제안 (권한보다 용서를 요청하기 쉽게) 코딩 스타일 EAFP을 . 이것은 코드가

try:
    os.makedirs(path)
except OSError as exception:
    if exception.errno != errno.EEXIST:
        raise
    else:
        print "\nBE CAREFUL! Directory %s already exists." % path

대안보다 낫다

if not os.path.exists(path):
    os.makedirs(path)
else:
    print "\nBE CAREFUL! Directory %s already exists." % path

문서는이 질문에서 논의 된 경쟁 조건으로 인해 정확하게 제안합니다. 또한 다른 사람들이 여기에 언급했듯이 OS를 두 배로 늘리는 대신 한 번 쿼리하면 성능 이점이 있습니다. 마지막으로, 어떤 경우에는 개발자가 응용 프로그램이 실행중인 환경을 알고있는 경우에 두 번째 코드를 선호하여이 주장이 제기되어 프로그램이 전용 환경을 설정 한 특별한 경우에만 옹호 될 수 있습니다. 자체 (및 동일한 프로그램의 다른 인스턴스).

이 경우에도 이것은 나쁜 습관이며 오랫동안 쓸모없는 디버깅으로 이어질 수 있습니다. 예를 들어, 디렉토리에 대한 권한을 설정한다는 사실은 노출 권한이 목적에 맞게 설정되어 있지 않아야합니다. 상위 디렉토리는 다른 권한으로 마운트 될 수 있습니다. 일반적으로 프로그램은 항상 올바르게 작동해야하며 프로그래머는 특정 환경을 기 대해서는 안됩니다.


11

에서 Python3 , os.makedirs지원은 설정 exist_ok. 기본 설정은 False입니다. 즉 OSError, 대상 디렉토리가 이미 존재하면가 발생합니다. 설정하면 exist_okTrue, OSError(디렉토리가) 무시되고 디렉토리가 작성되지 않습니다.

os.makedirs(path,exist_ok=True)

에서 Python2 , os.makedirs설정을 지원하지 않습니다 exist_ok. heikki-toivonen의 답변 에서 접근 방식을 사용할 수 있습니다 .

import os
import errno

def make_sure_path_exists(path):
    try:
        os.makedirs(path)
    except OSError as exception:
        if exception.errno != errno.EEXIST:
            raise

11

단일 라이너 솔루션의 경우 다음을 사용할 수 있습니다 IPython.utils.path.ensure_dir_exists().

from IPython.utils.path import ensure_dir_exists
ensure_dir_exists(dir)

로부터 문서 : 디렉토리가 존재하는지 확인합니다. 존재하지 않는 경우 다른 프로세스가 동일한 작업을 수행하는 경우이를 작성하고 경쟁 조건으로부터 보호하십시오.


새로운 IPython 설명서가 여기에 있습니다 .
jkdev

3
IPython모듈은 절대적으로 존재하는 것으로 보장 할 수 없습니다. 기본적으로 내 Mac에는 있지만 Linux의 Python 설치에는 없습니다. 기본적으로 Python Module Index에 나열된 모듈 중 하나가 아닙니다 .
Acumenus

1
확실한. 패키지를 설치하려면 평소대로 실행 pip install ipython하거나 requirements.txt 또는 pom.xml에 종속성을 포함하십시오 . 설명서 : ipython.org/install.html
tashuhka

9

당신이 사용할 수있는 mkpath

# Create a directory and any missing ancestor directories. 
# If the directory already exists, do nothing.

from distutils.dir_util import mkpath
mkpath("test")    

또한 조상 디렉토리도 생성합니다.

파이썬 2와 3에서 작동합니다.


2
distutils.dir_utildistutil 공용 API의 일부가 아니며 멀티 스레드 환경에서 문제가 있습니다. bugs.python.org/issue10948
Pod

1
예. 버그 의 첫 번째 메시지 에서 언급했듯이 문제 distutils.dir_util.mkpath는 디렉토리를 생성 한 다음 파이썬 내부 또는 외부에서 디렉토리를 삭제 한 다음 mkpath다시 mkpath사용하면 이전에 디렉토리를 생성 한 잘못된 캐시 된 정보를 사용한다는 것입니다. 실제로 디렉토리를 다시 만들지는 않습니다. 대조적으로, os.makedirs그러한 캐시에 의존하지 않습니다.
Acumenus

8

내가 사용 os.path.exists(), 여기에 디렉토리가 존재하는지 확인하는 데 사용할 수있는 파이썬 3 스크립트, 존재하지 않는 경우를 작성하고 (필요한 경우)가 존재 않는 경우 삭제합니다.

디렉토리를 입력하라는 메시지를 표시하며 쉽게 수정할 수 있습니다.


6

os.listdir이것을 위해 사용할 수 있습니다 :

import os
if 'dirName' in os.listdir('parentFolderPath')
    print('Directory Exists')

이것은 질문에 대답하지 않습니다
Georgy

6

나는이 Q / A를 발견했고 처음에 내가 겪고있는 몇 가지 실패와 오류에 당황했습니다. Python 3 (Arch Linux x86_64 시스템의 Anaconda 가상 환경에서 v.3.5)에서 일하고 있습니다.

이 디렉토리 구조를 고려하십시오.

└── output/         ## dir
   ├── corpus       ## file
   ├── corpus2/     ## dir
   └── subdir/      ## dir

다음은 실험 / 노트입니다.

# ----------------------------------------------------------------------------
# [1] /programming/273192/how-can-i-create-a-directory-if-it-does-not-exist

import pathlib

""" Notes:
        1.  Include a trailing slash at the end of the directory path
            ("Method 1," below).
        2.  If a subdirectory in your intended path matches an existing file
            with same name, you will get the following error:
            "NotADirectoryError: [Errno 20] Not a directory:" ...
"""
# Uncomment and try each of these "out_dir" paths, singly:

# ----------------------------------------------------------------------------
# METHOD 1:
# Re-running does not overwrite existing directories and files; no errors.

# out_dir = 'output/corpus3'                ## no error but no dir created (missing tailing /)
# out_dir = 'output/corpus3/'               ## works
# out_dir = 'output/corpus3/doc1'           ## no error but no dir created (missing tailing /)
# out_dir = 'output/corpus3/doc1/'          ## works
# out_dir = 'output/corpus3/doc1/doc.txt'   ## no error but no file created (os.makedirs creates dir, not files!  ;-)
# out_dir = 'output/corpus2/tfidf/'         ## fails with "Errno 20" (existing file named "corpus2")
# out_dir = 'output/corpus3/tfidf/'         ## works
# out_dir = 'output/corpus3/a/b/c/d/'       ## works

# [2] https://docs.python.org/3/library/os.html#os.makedirs

# Uncomment these to run "Method 1":

#directory = os.path.dirname(out_dir)
#os.makedirs(directory, mode=0o777, exist_ok=True)

# ----------------------------------------------------------------------------
# METHOD 2:
# Re-running does not overwrite existing directories and files; no errors.

# out_dir = 'output/corpus3'                ## works
# out_dir = 'output/corpus3/'               ## works
# out_dir = 'output/corpus3/doc1'           ## works
# out_dir = 'output/corpus3/doc1/'          ## works
# out_dir = 'output/corpus3/doc1/doc.txt'   ## no error but creates a .../doc.txt./ dir
# out_dir = 'output/corpus2/tfidf/'         ## fails with "Errno 20" (existing file named "corpus2")
# out_dir = 'output/corpus3/tfidf/'         ## works
# out_dir = 'output/corpus3/a/b/c/d/'       ## works

# Uncomment these to run "Method 2":

#import os, errno
#try:
#       os.makedirs(out_dir)
#except OSError as e:
#       if e.errno != errno.EEXIST:
#               raise
# ----------------------------------------------------------------------------

결론 : 제 생각에는 "방법 2"가 더 강력합니다.

[1] 디렉토리가 없으면 어떻게 만들 수 있습니까?

[2] https://docs.python.org/3/library/os.html#os.makedirs


6

나는 Heikki ToivonenABB 의 답변을 보았고이 변형에 대해 생각했습니다.

import os
import errno

def make_sure_path_exists(path):
    try:
        os.makedirs(path)
    except OSError as exception:
        if exception.errno != errno.EEXIST or not os.path.isdir(path):
            raise


5

지원하는 명령하는 컴퓨터에서 실행하면 왜 서브 프로세스 모듈을 사용 mkdir하여 -p옵션? Python 2.7 및 Python 3.6에서 작동

from subprocess import call
call(['mkdir', '-p', 'path1/path2/path3'])

대부분의 시스템에서 트릭을 수행해야합니다.

이식성이 중요하지 않은 상황 (예 : 도커 사용)에서 솔루션은 깔끔한 2 줄입니다. 또한 디렉토리가 존재하는지 여부를 확인하기 위해 로직을 추가 할 필요가 없습니다. 마지막으로 부작용없이 다시 실행하는 것이 안전합니다.

오류 처리가 필요한 경우 :

from subprocess import check_call
try:
    check_call(['mkdir', '-p', 'path1/path2/path3'])
except:
    handle...

4

다음을 고려하면 :

os.path.isdir('/tmp/dirname')

디렉토리 (경로)가 존재하고 디렉토리임을 의미합니다. 그래서 나를 위해이 방법은 내가 필요한 것을합니다. 따라서 폴더 (파일이 아닌)이고 존재하는지 확인할 수 있습니다.


이것이 디렉토리 작성에 대한 질문에 어떻게 대답 합니까?
Georgy

3

create_dir()프로그램 / 프로젝트의 시작점에서 함수 를 호출하십시오 .

import os

def create_dir(directory):
    if not os.path.exists(directory):
        print('Creating Directory '+directory)
        os.makedirs(directory)

create_dir('Project directory')

3

디렉토리를 작성하기 전에 전체 경로를 설정해야합니다.

import os,sys,inspect
import pathlib

currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
your_folder = currentdir + "/" + "your_folder"

if not os.path.exists(your_folder):
   pathlib.Path(your_folder).mkdir(parents=True, exist_ok=True)

이것은 나를 위해 작동하며 희망적으로도 당신을 위해 작동합니다


1
import os
if os.path.isfile(filename):
    print "file exists"
else:
    "Your code here"

여기 코드가 (touch) 명령을 사용하는 곳

파일이 없으면 파일이 있는지 확인한 다음 파일을 만듭니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.