programing

경로의 대상에 파일을 만들지 않고 Python에서 경로가 유효한지 확인합니다.

css3 2023. 8. 8. 21:48

경로의 대상에 파일을 만들지 않고 Python에서 경로가 유효한지 확인합니다.

경로(디렉토리 및 파일 이름 포함)가 있습니다.
파일 이름이 유효한지 테스트해야 합니다. 예를 들어 파일 시스템에서 해당 이름으로 파일을 만들 수 있는지 테스트해야 합니다.
파일 이름에 일부 유니코드 문자가 들어 있습니다.

경로의 디렉터리 세그먼트가 유효하고 액세스할 I was trying to make the question more gnerally applicable, and apparently I wen too far수 있다고 가정하는 것이 안전합니다().

저는 제가 해야만 하는 것이 아니라면 어떤 것도 탈출하고 싶지 않습니다.

제가 다루고 있는 몇 가지 예시 캐릭터를 게시하고 싶지만, 스택 교환 시스템에 의해 자동으로 제거되는 것 같습니다.어쨌든, 나는 표준 유니코드 엔티티를 유지하고 싶습니다.ö파일 이름에 잘못된 항목만 이스케이프합니다.


여기 함정이 있습니다.경로의 대상에 파일이 이미 있거나 없을 수 있습니다.해당 파일이 있으면 보관하고, 없으면 파일을 만들지 않아야 합니다.

기본적으로 실제로 쓰기 경로를 열지 않고도 경로에 쓸 수 있는지 확인하고 싶습니다(일반적으로 수반되는 자동 파일 생성/파일 클로빙).

다음과 같은 경우:

try:
    open(filename, 'w')
except OSError:
    # handle error here

여기서부터

터치하지 않을 기존 파일(있는 경우)을 덮어쓰거나, 터치하지 않을 경우 해당 파일을 만들기 때문에 허용되지 않습니다.

제가 할 수 있다는 것을 압니다.

if not os.access(filePath, os.W_OK):
    try:
        open(filePath, 'w').close()
        os.unlink(filePath)
    except OSError:
        # handle error here

하지만 그렇게 하면 파일이 생성됩니다.filePath그러면 나는 그래야 할 것입니다.os.unlink.

6~7줄 정도로 해야 할 것 요.os.isvalidpath(filePath)또는 그와 유사합니다.


별도로 Windows 및 MacOS에서 실행하려면 이 기능이 필요하므로 플랫폼 관련 작업은 피하고 싶습니다.

``

tl;dr

에게 하세요.is_path_exists_or_creatable()아래 정의된 함수입니다.

엄밀히 말하면 파이썬 3.그게 우리가 굴러가는 방식입니다.

두 가지 질문에 대한 이야기

"경로 이름 유효성과 유효한 경로 이름에 대해 해당 경로의 존재 또는 쓰기 가능성을 테스트하려면 어떻게 해야 합니까?"라는 질문은 분명히 두 가지 별개의 질문입니다.둘 다 흥미롭고, 둘 다 여기서 진정으로 만족스러운 답변을 받지 못했습니다.아니면, 음, 가 갈 수 있는 곳이라면 어디든요.

비키대답은 아마도 가장 가까운 것일 것이지만, 다음과 같은 놀라운 단점이 있습니다.

  • 불필요하게 파일 핸들을 열어서 안정적으로 닫지 못합니다.
  • 불필요하게 0바이트 파일 쓰기(...신뢰할 수 있는 닫기 또는 삭제 실패)
  • 무시할 수 없는 잘못된 경로 이름과 무시할 수 없는 파일 시스템 문제를 구분하는 OS별 오류를 무시합니다.당연히 Windows에서는 이 작업이 매우 중요합니다.(아래 참조).
  • 테스트할 경로 이름의 상위 디렉터리를 동시에 이동(재이동)하는 외부 프로세스로 인해 발생하는 경합 조건을 무시합니다.(아래 참조).
  • 오래되거나 느리거나 일시적으로 액세스할 수 없는 파일 시스템에 있는 이 경로 이름으로 인해 발생하는 연결 시간 초과를 무시합니다.로 인해 공공 서비스가 잠재적인 DoS 주도 공격에 노출될 수 있습니다.(아래 참조).

우리가 다 해결할 겁니다

질문 #0: 경로 이름 유효성이란 무엇입니까?

우리의 연약한 고기 슈트를 비단뱀이 우글거리는 고통의 모기장에 던지기 전에, 우리는 아마도 우리가 의미하는 "경로 이름 타당성"을 정의해야 할 것입니다.정확하게 무엇이 타당성을 정의합니까?

"경로 이름 유효성"은 경로 또는 상위 디렉터리가 물리적으로 존재하는지 여부에 관계없이 현재 시스템의 루트 파일 시스템에 대한 경로 이름의 구문적 정확성을 의미합니다.경로 이름이 루트 파일 시스템의 모든 구문 요구 사항을 준수하는 경우 이 정의에 따라 구문적으로 올바른 이름입니다.

"루트 파일 시스템"은 다음을 의미합니다.

  • POSIX 시스템의 경우 POSIX 호스에서템파일시스은템루마다니운됩트에디)에 마운트된 입니다./).
  • Windows에 %HOMEDRIVE%현재 Windows 설치가 포함된 콜론 접미사 드라이브 문자(일반적으로 반드시 필요한 것은 아님)C:).

"통사적 정확성"의 의미는 차례로 루트 파일 시스템의 유형에 따라 다릅니다.ext4( 대부분의 POSIX 호환은 아님) 파일 시스템, 경로 이름은 다음과 같은 경우에만 구문적으로 정확합니다.

  • 바이트 null 바를포즉않습지니다하함이트즉(▁(,\x00Python)로 표시됩니다.이것은 모든 POSIX 호환 파일 시스템에 대한 어려운 요구 사항입니다.
  • 긴 요소를 포함하지 않습니다( "255" " " " " " " " ").'a'*256Python)로 표시됩니다.경로 구성 요소는 다음을 포함하지 않는 경로 이름의 가장 긴 하위 문자열입니다./ 문자):bergtatt,ind,i,그리고.fjeldkamrene 이름 가으로로/bergtatt/ind/i/fjeldkamrene).

통사적 정확성.루트 파일 시스템.바로 그겁니다.

질문 #1: 이제 경로 이름 유효성을 어떻게 해야 합니까?

Python에서 경로 이름을 검증하는 것은 의외로 직관적이지 않습니다.저는 여기서 가짜 이름에 확고한 동의를 합니다: 관계자.os.path패키지는 이에 대한 즉각적인 솔루션을 제공해야 합니다.알 수 없는(그리고 아마도 설득력이 없는) 이유로, 그렇지 않습니다.다행스럽게도, 애드혹 솔루션을 공개하는 것은 그렇게 고통스럽지 않습니다.

좋아요, 사실 그렇습니다.그것은 털이 많고, 심술궂습니다. 아마도 빛나면서 트림을 하고 낄낄거리기도 합니다.하지만 어떻게 할 겁니까?'누틴'.

우리는 곧 저수준 코드의 방사능 심연으로 내려갈 것입니다.하지만 먼저 고급 상점에 대해 이야기해 보겠습니다.os.stat()그리고.os.lstat()함수는 잘못된 경로 이름을 전달할 때 다음 예외를 발생시킵니다.

  • 하지 않는 이름의 , "" " " " " " "의 ,FileNotFoundError.
  • 기존 디렉토리에 있는 경로 이름의 경우:
    • 는 다음과 같습니다.WindowsError의 집입니까?winerror은 속은입니다.123 (계속)ERROR_INVALID_NAME).
    • 다른 모든 OS에서:
    • 바이트를 null 바트즉(이, null 바트를))의 경우 "는 " " "입니다.'\x00' , 의TypeError.
    • 보다 긴 구성 이름의 경우 255개의 .OSError의 집입니까?errcode속성:
      • 아래에서 SunOS 및 *BSD OS는errno.ERANGE의 " 해석"이라고도 OS 버그로
      • 에서 다모에 OS든errno.ENAMETOOLONG.

결정적으로 이는 기존 디렉터리에 있는 경로 이름만 유효하다는 것을 의미합니다.os.stat()그리고.os.lstat() generic 함상제릭네승수▁functionsFileNotFoundError경로 이름이 유효하지 않은지 여부에 관계없이 전달된 경로 이름이 존재하지 않는 디렉터리에 있을 때 예외가 발생합니다.디렉터리 존재가 경로 이름의 유효성보다 우선합니다.

이것은 존재하지 않는 디렉토리에 있는 경로 이름이 유효하지 않음을 의미합니까?예 – 이러한 경로 이름을 기존 디렉터리에 저장하도록 수정하지 않는 한 그렇습니다.하지만 그것이 안전하게 실현 가능한가요?경로 이름을 수정하면 원래 경로 이름의 유효성을 검사할 수 없게 되지 않습니까?

이 질문에 답하려면 위에서 구문적으로 올바른 경로 이름을 기억하십시오.ext4파일 시스템에 Null 바이트를 포함하는 경로 구성 요소(A) 또는 길이가 255바이트를 초과하는 (B)가 없습니다.그러므로,ext4 경로 이름은 해당 경로 이름의 모든 경로 구성 요소가 유효한 경우에만 유효합니다.이는 관심 있는 대부분실제 파일 시스템에 해당됩니다.

현학적인 통찰력이 실제로 우리에게 도움이 될까요?예. 그러면 전체 경로 이름을 한 번에 확인하는 더 큰 문제가 해당 경로 이름의 모든 경로 구성 요소만 확인하는 더 작은 문제로 줄어듭니다.임의의 경로 이름은 다음 알고리즘을 따라 교차 플랫폼 방식으로 유효합니다(해당 경로 이름이 기존 디렉터리에 있는지 여부와 관계없이).

  1. 요소 이름 " 예구로요을경로성소분이할름해이경름(예: " " " ") "로 합니다./troldskog/faren/vild에.['', 'troldskog', 'faren', 'vild']).
  2. 이러한 각 구성 요소에 대해:
    1. 요소와 새 이름 해당구예디경이새임경이름로시을성름로요소토와리된의렉함장)에 가입시킵니다./troldskog) .
    2. 그 을 해당경이전대상달로 합니다.os.stat()또는os.lstat() 구성 가 유효하지 않은 이인 해당이및해당구요유성소않효은지경이 무효 시킵니다.FileNotFoundError예외입니다. 왜죠?해당 경로 이름이 기존 디렉터리에 있기 때문입니다. (원형 논리는 원형입니다.)

존재하도록 보장된 디렉토리가 있습니까?예, 그러나 일반적으로 루트 파일 시스템의 최상위 디렉터리(위에서 정의됨)만 있습니다.

되지 않음)을 "" " " " " " " " (" " " " " " " " " " 로 전달합니다.os.stat()또는os.lstat()해당 디렉토리가 이전에 존재하는 것으로 테스트된 경우에도 인종 조건을 초대합니다. 왜죠?외부 프로세스는 해당 테스트를 수행한 후 해당 경로 이름이 에 전달되기 전에 해당 디렉토리를 동시에 제거하는 것을 방지할 수 없기 때문입니다.os.stat()또는os.lstat()정신이 혼미한 개들을 풀어주시오!

위의 접근 방식에는 보안이라는 상당한 부수적인 이점도 있습니다.(좋지 않나요?)구체적으로:

할 수 없는 신할 수없 소는의임스검으로 하여 검증하는 전면 입니다.os.stat()또는os.lstat()서비스 거부(DoS) 공격 및 기타 블랙햇 쉐넌건에 취약합니다.악의적인 사용자는 오래되거나 느린 것으로 알려진 파일 시스템(예: NFS Samba 공유)에 상주하는 경로 이름을 반복적으로 검증하려고 할 수 있습니다. 이 경우 수신 경로 이름을 맹목적으로 표시하면 결국 연결 시간 초과로 실패하거나 실업을 견딜 수 있는 미약한 용량보다 더 많은 시간과 리소스를 소비할 수 있습니다.

위의 접근 방식은 루트 파일 시스템의 루트 디렉터리에 대해 경로 이름의 경로 구성 요소만 검증하여 이 문제를 방지합니다.(그마저도 오래되었거나, 느리거나, 액세스할 수 없는 경우에는 경로 이름 검증보다 더 큰 문제가 발생합니다.)

길을 잃었다고요? 좋습니다.시작합니다.(피톤 3을 가정했습니다."300에게 깨지기 쉬운 희망이란 무엇인가, 레이섹?"을 참조하십시오.")

import errno, os

# Sadly, Python fails to provide the following magic number for us.
ERROR_INVALID_NAME = 123
'''
Windows-specific error code indicating an invalid pathname.

See Also
----------
https://learn.microsoft.com/en-us/windows/win32/debug/system-error-codes--0-499-
    Official listing of all such codes.
'''

def is_pathname_valid(pathname: str) -> bool:
    '''
    `True` if the passed pathname is a valid pathname for the current OS;
    `False` otherwise.
    '''
    # If this pathname is either not a string or is but is empty, this pathname
    # is invalid.
    try:
        if not isinstance(pathname, str) or not pathname:
            return False

        # Strip this pathname's Windows-specific drive specifier (e.g., `C:\`)
        # if any. Since Windows prohibits path components from containing `:`
        # characters, failing to strip this `:`-suffixed prefix would
        # erroneously invalidate all valid absolute Windows pathnames.
        _, pathname = os.path.splitdrive(pathname)

        # Directory guaranteed to exist. If the current OS is Windows, this is
        # the drive to which Windows was installed (e.g., the "%HOMEDRIVE%"
        # environment variable); else, the typical root directory.
        root_dirname = os.environ.get('HOMEDRIVE', 'C:') \
            if sys.platform == 'win32' else os.path.sep
        assert os.path.isdir(root_dirname)   # ...Murphy and her ironclad Law

        # Append a path separator to this directory if needed.
        root_dirname = root_dirname.rstrip(os.path.sep) + os.path.sep

        # Test whether each path component split from this pathname is valid or
        # not, ignoring non-existent and non-readable path components.
        for pathname_part in pathname.split(os.path.sep):
            try:
                os.lstat(root_dirname + pathname_part)
            # If an OS-specific exception is raised, its error code
            # indicates whether this pathname is valid or not. Unless this
            # is the case, this exception implies an ignorable kernel or
            # filesystem complaint (e.g., path not found or inaccessible).
            #
            # Only the following exceptions indicate invalid pathnames:
            #
            # * Instances of the Windows-specific "WindowsError" class
            #   defining the "winerror" attribute whose value is
            #   "ERROR_INVALID_NAME". Under Windows, "winerror" is more
            #   fine-grained and hence useful than the generic "errno"
            #   attribute. When a too-long pathname is passed, for example,
            #   "errno" is "ENOENT" (i.e., no such file or directory) rather
            #   than "ENAMETOOLONG" (i.e., file name too long).
            # * Instances of the cross-platform "OSError" class defining the
            #   generic "errno" attribute whose value is either:
            #   * Under most POSIX-compatible OSes, "ENAMETOOLONG".
            #   * Under some edge-case OSes (e.g., SunOS, *BSD), "ERANGE".
            except OSError as exc:
                if hasattr(exc, 'winerror'):
                    if exc.winerror == ERROR_INVALID_NAME:
                        return False
                elif exc.errno in {errno.ENAMETOOLONG, errno.ERANGE}:
                    return False
    # If a "TypeError" exception was raised, it almost certainly has the
    # error message "embedded NUL character" indicating an invalid pathname.
    except TypeError as exc:
        return False
    # If no exception was raised, all path components and hence this
    # pathname itself are valid. (Praise be to the curmudgeonly python.)
    else:
        return True
    # If any other exception was raised, this is an unrelated fatal issue
    # (e.g., a bug). Permit this exception to unwind the call stack.
    #
    # Did we mention this should be shipped with Python already?

됐어, 코드를 보고 눈을 가늘게 뜨지 마(물어요.)

질문 #2: 잘못된 경로 이름 존재 또는 생성 가능성, 어?

잘못된 경로 이름의 존재 또는 생성 가능성을 테스트하는 것은 위의 솔루션을 고려할 때 대부분 사소한 일입니다.여기서 중요한 것은 전달된 경로를 테스트하기 전에 이전에 정의된 함수를 호출하는 것입니다.

def is_path_creatable(pathname: str) -> bool:
    '''
    `True` if the current user has sufficient permissions to create the passed
    pathname; `False` otherwise.
    '''
    # Parent directory of the passed path. If empty, we substitute the current
    # working directory (CWD) instead.
    dirname = os.path.dirname(pathname) or os.getcwd()
    return os.access(dirname, os.W_OK)

def is_path_exists_or_creatable(pathname: str) -> bool:
    '''
    `True` if the passed pathname is a valid pathname for the current OS _and_
    either currently exists or is hypothetically creatable; `False` otherwise.

    This function is guaranteed to _never_ raise exceptions.
    '''
    try:
        # To prevent "os" module calls from raising undesirable exceptions on
        # invalid pathnames, is_pathname_valid() is explicitly called first.
        return is_pathname_valid(pathname) and (
            os.path.exists(pathname) or is_path_creatable(pathname))
    # Report failure on non-fatal filesystem complaints (e.g., connection
    # timeouts, permissions issues) implying this path to be inaccessible. All
    # other exceptions are unrelated fatal issues and should not be caught here.
    except OSError:
        return False

끝까지.아직은 아니지만요.

질문 3: Windows에 잘못된 경로 이름이 있거나 쓰기 가능성이 있을 수 있습니다.

경고가 있습니다.물론 있습니다.

공식 문서에서 인정하는 바와 같이:

참고: 다음과 같은 경우에도 I/O 작업이 실패할 수 있습니다.os.access()는 특히 일반적인 POSIX 권한 비트 모델을 초과하는 권한 의미론을 가질 수 있는 네트워크 파일 시스템의 작업에 대해 성공할 것임을 나타냅니다.

놀랄 것도 없이 Windows가 일반적인 용의자입니다.NTFS 파일 시스템에서 ACL(Access Control List)을 광범위하게 사용하기 때문에 단순한 POSIX 권한 비트 모델은 기본 Windows 현실과 제대로 매핑되지 않습니다.Python의 잘못은 아니지만 Windows 호환 애플리케이션의 경우 문제가 될 수 있습니다.

만약 이것이 당신이라면, 더 강력한 대안이 필요합니다.전달된 경로가 존재하지 않는 경우에는 해당 경로의 상위 디렉터리에서 즉시 삭제되도록 보장하는 임시 파일을 생성합니다. 즉, 보다 휴대성이 높은(비용이 많이 드는) 생성 테스트입니다.

import os, tempfile

def is_path_sibling_creatable(pathname: str) -> bool:
    '''
    `True` if the current user has sufficient permissions to create **siblings**
    (i.e., arbitrary files in the parent directory) of the passed pathname;
    `False` otherwise.
    '''
    # Parent directory of the passed path. If empty, we substitute the current
    # working directory (CWD) instead.
    dirname = os.path.dirname(pathname) or os.getcwd()

    try:
        # For safety, explicitly close and hence delete this temporary file
        # immediately after creating it in the passed path's parent directory.
        with tempfile.TemporaryFile(dir=dirname): pass
        return True
    # While the exact type of exception raised by the above function depends on
    # the current version of the Python interpreter, all such types subclass the
    # following exception superclass.
    except EnvironmentError:
        return False

def is_path_exists_or_creatable_portable(pathname: str) -> bool:
    '''
    `True` if the passed pathname is a valid pathname on the current OS _and_
    either currently exists or is hypothetically creatable in a cross-platform
    manner optimized for POSIX-unfriendly filesystems; `False` otherwise.

    This function is guaranteed to _never_ raise exceptions.
    '''
    try:
        # To prevent "os" module calls from raising undesirable exceptions on
        # invalid pathnames, is_pathname_valid() is explicitly called first.
        return is_pathname_valid(pathname) and (
            os.path.exists(pathname) or is_path_sibling_creatable(pathname))
    # Report failure on non-fatal filesystem complaints (e.g., connection
    # timeouts, permissions issues) implying this path to be inaccessible. All
    # other exceptions are unrelated fatal issues and should not be caught here.
    except OSError:
        return False

그러나 마저도 충분하지 않을 수 있습니다.

UAC(사용자 액세스 제어) 덕분에 Windows Vista 및 그 이후의 모든 반복 작업은 시스템 디렉토리와 관련된 권한에 대해 노골적으로 거짓말을 합니다.관리자가 아닌 사용자가 표준 파일 중 하나로 파일을 작성하려고 할 때C:\Windows또는C:\Windows\system32UAC는 실제로 생성된 모든 파일을 해당 사용자 프로필의 "가상 저장소"로 분리하면서 사용자에게 표면적으로 허용합니다.(사용자를 속이는 것이 장기적으로 해로운 결과를 초래할 것이라고 누가 상상이나 했겠습니까?)

이건 미친 짓이야.이것은 Windows입니다.

증명해봐.

우리가 감히?위의 테스트를 시승할 시간입니다.

UNIX 지향 파일 시스템에서 경로 이름에서 NULL이 금지된 유일한 문자이기 때문에, NULL을 활용하여 냉혹하고 냉혹한 진실을 입증해 보겠습니다. 무시할 수 없는 Windows shenanigan을 무시하고 동일한 기준으로 저를 지루하고 화나게 만들었습니다.

>>> print('"foo.bar" valid? ' + str(is_pathname_valid('foo.bar')))
"foo.bar" valid? True
>>> print('Null byte valid? ' + str(is_pathname_valid('\x00')))
Null byte valid? False
>>> print('Long path valid? ' + str(is_pathname_valid('a' * 256)))
Long path valid? False
>>> print('"/dev" exists or creatable? ' + str(is_path_exists_or_creatable('/dev')))
"/dev" exists or creatable? True
>>> print('"/dev/foo.bar" exists or creatable? ' + str(is_path_exists_or_creatable('/dev/foo.bar')))
"/dev/foo.bar" exists or creatable? False
>>> print('Null byte exists or creatable? ' + str(is_path_exists_or_creatable('\x00')))
Null byte exists or creatable? False

제정신이 아닌.고통을 넘어서.Python 휴대성 문제를 발견하게 될 것입니다.

if os.path.exists(filePath):
    #the file is there
elif os.access(os.path.dirname(filePath), os.W_OK):
    #the file does not exists but write privileges are given
else:
    #can not write there

:path.exists단순한 이유 이상으로 실패할 수 있습니다.the file is not there따라서 포함된 디렉터리가 있는지 테스트하는 등의 세부 테스트를 수행해야 할 수 있습니다.


OP와 논의한 결과 파일 이름에 파일 시스템에서 허용하지 않는 문자가 포함되어 있는 것으로 나타났습니다.물론 제거해야 하지만 OP는 파일 시스템이 허용하는 한 인간의 가독성을 유지하기를 원합니다.

안타깝게도 저는 이것에 대한 어떤 좋은 해결책도 모릅니다.그러나 Cecil Curry의 대답은 문제를 탐지하는 것을 자세히 살펴봅니다.

라는 PyPI 모듈을 찾았습니다.

pip install pathvalidate

그 안에는 다음과 같은 기능이 있습니다.sanitize_filepath파일 경로를 사용하여 유효한 파일 경로로 변환합니다.

from pathvalidate import sanitize_filepath
file1 = "ap:lle/fi:le"
print(sanitize_filepath(file1))
# Output: "apple/file"

예약된 이름으로도 작동합니다.파일 경로를 입력하는 경우con돌아올 것입니다.con_.

이러한 지식을 바탕으로 입력한 파일 경로가 검사된 경로와 동일한지 확인할 수 있으며, 이는 파일 경로가 유효함을 의미합니다.

import os
from pathvalidate import sanitize_filepath

def check(filePath):
    if os.path.exists(filePath):
        return True
    if filePath == sanitize_filepath(filePath):
        return True
    return False

Python 3에서는 다음과 같은 이점이 있습니다.

try:
    with open(filename, 'x') as tempfile: # OSError if file exists or is invalid
        pass
except OSError:
    # handle error here

'x' 옵션을 사용하면 경주 조건에 대해서도 걱정할 필요가 없습니다.여기에서 설명서를 참조하십시오.

이름이 올바르지 않은 경우를 제외하고 이미 존재하지 않는 경우에는 매우 짧은 기간의 임시 파일이 만들어집니다.만약 당신이 그것을 견딜 수 있다면, 그것은 많은 것을 단순화합니다.

open(filename,'r')   #2nd argument is r and not w

파일이 없으면 파일을 열거나 오류를 표시합니다.오류가 있으면 경로에 쓰려고 시도할 수 있고, 그렇지 않으면 두 번째 오류가 발생합니다.

try:
    open(filename,'r')
    return True
except IOError:
    try:
        open(filename, 'w')
        return True
    except IOError:
        return False

또한 창에 대한 권한에 대해서도 살펴보십시오.

시도해 보세요. 이것은 경로를 확인하고 돌아올 것입니다.True 존재한다면 그리고 존하는경및우재및.False아니라면.

언급URL : https://stackoverflow.com/questions/9532499/check-whether-a-path-is-valid-in-python-without-creating-a-file-at-the-paths-ta