python - 파이썬 상위 디렉토리 입력




파이썬에서 중첩 된 디렉토리를 안전하게 만들려면 어떻게해야합니까? (17)

파일이 저장 될 디렉토리가 존재하는지 확인하는 가장 우아한 방법은 무엇이며, 그렇지 않다면 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, 블레어, 더글러스)를 놓쳤다. 이것은 내가 지금 가지고있는 것입니다 :

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

"open"에 대한 플래그가 있습니까? 그러면 자동으로 실행됩니까?

https://code.i-harness.com


디렉토리가 있는지 확인하고 필요한 경우 디렉토리를 만드시겠습니까?

이에 대한 직접적인 대답은 다른 사용자 나 프로세스가 디렉토리를 망칠 수 있다고 생각하지 않는 간단한 상황을 전제로합니다.

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.

파이썬 3.5의 새로운 기능 : pathlib.Path with exist_ok

Path 와 함께 사용하고자하는 메소드가 많은 새로운 Path 객체 (3.4 절)가 있는데, 그 중 하나는 mkdir 입니다.

(컨텍스트에 대해 스크립트로 내 주간 담당자를 추적하고 있습니다. 스크립트의 관련 코드 부분에서 동일한 데이터에 대해 하루에 두 번 이상 스택 오버플로가 발생하지 않도록 할 수 있습니다.)

먼저 해당 수입품 :

from pathlib import Path
import tempfile

os.path.join 을 처리 할 필요가 없습니다. - 경로 부분을 / 와 결합하십시오.

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

그런 다음 idempotently 디렉토리가 존재하는지 확인합니다 - exist_ok 인수가 파이썬 3.5에 나타납니다.

directory.mkdir(exist_ok=True)

다음은 pathlib.Path.mkdir 의 관련 부분입니다.

exist_ok 가 true 인 경우 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))

str 경로를 예상하는 다른 API가 Path 객체를 사용할 수 있으려면 먼저 Path 객체를 str 강제 변환해야합니다.

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


이 상황에 대한 통찰력

특정 경로에서 특정 파일을 지정하고 파일 경로에서 디렉토리를 가져옵니다. 그런 다음 디렉토리가 있는지 확인한 후 파일을 열어 읽으려고합니다. 이 코드에 대한 의견 :

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

우리는 내장 함수를 덮어 쓰지 않도록하고 싶다. 또한 filepath 또는 아마도 fullfilepathfilename 보다 더 나은 의미 론적 이름 일 수 있습니다.

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 모드로 열어야합니다 (또는를 추가해야합니다). 컨텍스트 관리자를 사용하여 파일을 여는 것도 파이썬의 가장 좋은 방법입니다.

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

그러나 모든 데이터를 동일한 디렉토리에 넣으려고하는 여러 파이썬 프로세스가 있다고 가정 해보십시오. 그런 다음 디렉토리 생성에 대한 논쟁이있을 수 있습니다. 이 경우 try-except 블록에서 makedirs 호출을 래핑하는 것이 가장 좋습니다.

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)

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.

try except와 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'를 미리 만들어서 모든 권한을 제거하면 errno.EACCES (Permission denied, error 13)와 함께 발생하는 OSError 발생합니다.


나는 다음과 같은 것을 내려 놓았다. 그것은 완전히 빠르지는 않습니다.

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

이제 내가 말했듯이, 이것은 디렉토리를 만드는 데 실패 할 가능성이 있고, 그 기간에 디렉토리를 생성 할 가능성이 있기 때문에 절대적으로 안전하지 않습니다.


나는 작은 결함이있는 좋은 자질을 가진 두 가지 대답을보고, 그래서 그것에 대한 나의 대답을 줄 것이다.

os.path.exists 시도해보고 작성을 위해 os.makedirs 를 고려하십시오.

import os
if not os.path.exists(directory):
    os.makedirs(directory)

주석과 다른 곳에서 언급했듯이 경쟁 조건이 있습니다 - 디렉토리가 os.path.existsos.makedirs 호출 사이에 생성되면 os.makedirsOSError 와 함께 실패합니다. 안타깝게도 OSError 포괄적으로 포착하고 계속해서 사용하는 것은 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 가있을 수 있지만 다른 하나는 첫 번째 검사 후 디렉토리를 만든 다음 두 번째 전에 제거한 것으로 가정합니다. 우리는 여전히 바보가 될 수 있습니다.

응용 프로그램에 따라 동시 조작의 위험은 파일 권한과 같은 다른 요인에 의해 야기되는 위험보다 많거나 적을 수 있습니다. 개발자는 구현을 선택하기 전에 개발중인 특정 응용 프로그램과 예상되는 환경에 대해 더 많이 알아야합니다.


다음 사항을 고려한 경우 :

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

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


쉘 언어를 지원하는 시스템에서 실행중인 경우 서브 프로세스 모듈을 사용하지 않는 이유는 무엇입니까? 파이썬 2.7 및 파이썬 3.6에서 작동합니다.

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

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


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

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

파이썬 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)

이 재귀 적으로 디렉터리를 만들고 디렉터리가 이미 있으면 예외를 발생시키지 않습니다.

( os.makedirs 가 파이썬 3.2부터 시작하는 exists_ok 플래그를 가지고있는 exists_ok ).


프로그램 / 프로젝트의 진입 점에서 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')

한 줄짜리 솔루션의 경우 IPython.utils.path.ensure_dir_exists() 사용할 수 있습니다.

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

documentation : 디렉토리가 존재하는지 확인하십시오. 존재하지 않는 경우 다른 프로세스가 동일한 작업을 수행하는 경우 해당 프로세스를 만들어 경쟁 조건으로부터 보호하십시오.


관련 Python 문서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의 두 배 대신 한 번 쿼리하는 것이 성능상 이점이 있습니다. 마지막으로, 경우에 따라 두 번째 코드를 우선적으로 고려한 인수가 개발자가 응용 프로그램이 실행되는 환경을 알고있을 때 프로그램이 개인 환경을 설정 한 특별한 경우에만 옹호 될 수 있습니다. 그 자체 (그리고 같은 프로그램의 다른 인스턴스들).

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


os.path.exists 함수를 사용해보십시오.

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

os.path.exists() . here 에 디렉토리가 존재하는지 확인하고, 존재하지 않으면 생성하고, 존재한다면 삭제할 수있는 Python 3 스크립트가 있습니다.

사용자에게 디렉토리 입력을 요구하며 쉽게 수정할 수 있습니다.


Python3 에서 os.makedirsexist_ok 설정을 지원합니다. 기본 설정은 False 입니다. 즉, 대상 디렉터리가 이미있는 경우 OSError 가 발생합니다. exist_okTrue 로 설정하면 OSError (디렉토리가 있음)가 무시되고 디렉토리가 생성되지 않습니다.

os.makedirs(path,exist_ok=True)

Python2 에서 os.makedirsexist_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

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

여기서 코드는 (touch) 명령을 사용하는 곳입니다.

이것은 파일이 존재하지 않는 경우 거기에 있는지 확인하여 생성하지 않습니다.





operating-system