파일이나 폴더가 파이썬에 존재하는지 확인하는 7가지 방법

파이썬에서 파일 및 디렉토리 존재 여부 확인하기

파이썬 표준 라이브러리는 개발자들이 다양한 문제를 해결하는 데 필요한 대부분의 도구를 제공합니다. 이 튜토리얼에서는 내장 모듈만을 이용하여 파일 또는 디렉토리의 존재를 검증하는 여러 가지 방법에 대해 알아볼 것입니다.

파일이나 스크립트가 정확한 위치에 있는지 확인하는 것은 모든 커맨드라인 인터페이스(CLI) 프로그램에서 매우 중요합니다. 특정 파일이 실행 시점에 존재하지 않으면 프로그램이 제대로 작동하지 않을 수 있습니다.

이번 튜토리얼에서는 파이썬에서 파일이나 폴더의 존재를 확인하는 몇 가지 간편한 방법을 소개합니다.

시작하기 전에

아래의 명령을 실행하기 전에 시스템에 파이썬 3 버전이 설치되어 있는지 확인하세요. 터미널을 열고 다음 명령을 입력합니다.

python --version
# 예시 출력: Python 3.9.5

만약 2.x 버전이 설치되어 있다면 “python3” 명령어를 사용해야 합니다. 파이썬 3가 설치되어 있지 않다면, 파이썬 설치 가이드를 참조하시기 바랍니다.

본 튜토리얼에서는 몇 가지 테스트 파일을 사용할 예정이므로, 다음 파일들을 생성해야 합니다.

touch testfile.txt
mkdir testdirectory/
touch testdirectory/otherfile.txt

위 명령들은 테스트용 파일, 테스트 디렉토리 및 테스트 디렉토리 내부에 또 다른 파일을 생성합니다. 파일 내용은 필요하지 않으므로 비워두셔도 좋습니다.

참고: Windows 운영체제 사용자라면 그래픽 파일 탐색기를 사용하여 동일한 파일 구조를 설정할 수 있습니다.

마지막으로, 우리는 IPython을 대화형 파이썬 셸로 활용하여 작업하기에 더 편리한 환경을 제공할 것입니다. 하지만 필수는 아닙니다.

pip install ipython

위 명령을 실행하면, “ipython”을 입력하여 강화된 파이썬 셸에 접근할 수 있습니다.

이제 모든 준비가 완료되었습니다. 파이썬에서 폴더 또는 파일의 존재 여부를 확인하는 다양한 방법을 살펴보겠습니다.

예외 처리 및 파일 열기 시도

이 방법은 가장 간단한 접근 방식입니다. 존재하지 않는 파일을 열려고 시도하면 파이썬은 FileNotFoundError 예외를 발생시킵니다.

In [1]: open('im-not-here.txt')
---------------------------------------------------------------------------
FileNotFoundError: [Errno 2] No such file or directory: 'im-not-here.txt'

이 예외를 활용하여 찾고 있는 파일이 존재하지 않을 때 예외를 처리할 수 있습니다.

In [2]: try:
   ...:     file = open('im-not-here.txt')
   ...:     print(file) # 파일 핸들러 출력
   ...:     file.close()
   ...: except FileNotFoundError:
   ...:     print('죄송합니다. 찾으시는 파일이 존재하지 않습니다.')
   ...:     exit()
   ...: 
죄송합니다. 찾으시는 파일이 존재하지 않습니다.

위 코드는 사용자 정의 메시지를 출력하고, 파일이 존재하지 않을 경우 프로그램 실행을 중단합니다.

exit() 함수는 예외가 발생했을 때만 실행된다는 점을 기억하세요. 찾고 있는 파일이 실제로 존재하는 경우에는 어떻게 될까요?

In [2]: try:
   ...:     file = open('testfile.txt')
   ...:     print(file) # 파일 핸들러 출력
   ...:     file.close()
   ...: except FileNotFoundError:
   ...:     print('죄송합니다. 찾으시는 파일이 존재하지 않습니다.')
   ...:     exit()
   ...: 
<_io.TextIOWrapper name="testfile.txt" mode="r" encoding='UTF-8'>

파일을 열자마자 바로 닫는 것에 주목하세요. 이것은 파이썬 문서에서 권장하는 좋은 습관입니다.

with 키워드를 사용하지 않거나 file.close()를 호출하지 않은 채 file.write()를 호출하면, 프로그램이 성공적으로 종료되더라도 file.write()의 인수가 디스크에 완전히 기록되지 않을 수 있습니다.

파일에 쓰지 않더라도 파일을 닫는 것은 여러 성능 문제를 피하기 위해 권장됩니다.

만약 직접 파일을 닫고 싶지 않다면, 컨텍스트 관리자와 함께 사용할 수 있습니다. 이렇게 하면 리소스가 정확하게 할당되고 해제되므로 파일을 닫을 필요가 없습니다.

In [3]: try:
   ...:     with open('testfile.txt') as file:
   ...:         print(file)
   ...:         # 파일 닫을 필요 없음
   ...: except FileNotFoundError:
   ...:     print('죄송합니다. 찾으시는 파일이 존재하지 않습니다.')
   ...:     exit()
   ...: 
<_io.TextIOWrapper name="testfile.txt" mode="r" encoding='UTF-8'>

이 방법은 파일에 쓸 때 매우 유용하지만, 파일의 존재 여부만 확인하려는 경우에는 비효율적입니다. 다른 옵션을 살펴보겠습니다.

os.path.exists()

os 모듈은 운영체제와 상호작용하는 다양한 기능을 제공합니다. 파일이나 폴더가 존재하는지 확인하기 위해, 파일이나 디렉토리의 경로를 인자로 받아 해당 경로의 존재 여부에 따라 boolean 값을 반환하는 path.exists() 함수를 사용할 수 있습니다.

참고: 경로는 파일 시스템에서 파일 또는 디렉토리의 고유한 위치입니다.

파이썬에서 os.path 하위 모듈은 파일 경로와 관련 작업을 수행하도록 특별히 설계된 기능들을 포함하고 있습니다. 이러한 함수들은 경로 인수를 문자열 또는 바이트로 허용하며, 다음과 같은 절대 경로를 사용하여 작업할 수 있습니다:

/home/daniel/.bashrc

또는 스크립트가 실행되는 디렉토리에 따라 상대 경로를 사용할 수 있습니다.

.bashrc
# 내 홈 폴더에서 스크립트 실행

다음은 테스트 파일이 위치한 디렉토리에서 os.path.exists() 함수를 사용하는 몇 가지 예시입니다.

In [1]: import os

In [2]: os.path.exists('testfile.txt')
Out[2]: True

In [3]: os.path.exists('testdirectory')
Out[3]: True

In [4]: os.path.exists('hey-i-dont-exist')
Out[4]: False

위에서 볼 수 있듯이, testfile.txt 파일과 testdirectory 폴더를 테스트할 때는 True를 반환하고, 존재하지 않는 파일에 대해서는 False를 반환합니다.

os.path.isfile()

만약 파일(디렉토리가 아님)의 존재만을 확인하고 싶다면, os.path.isfile() 함수를 호출합니다.

In [1]: import os

In [2]: os.path.isfile('testfile.txt')
Out[2]: True

In [3]: os.path.isfile('testdirectory/')
Out[3]: False

In [4]: os.path.isfile('i-dont-even-exist')
Out[4]: False

In [5]: os.path.isfile('testdirectory/otherfile.txt')
Out[5]: True

참고: 유닉스에서는 모든 디렉토리가 슬래시(/)로 끝나지만, 윈도우에서는 백슬래시(\)를 사용합니다.

위의 코드에서 isfile() 함수는 두 가지 경우에 False를 반환합니다. 그 이유를 살펴보겠습니다:

  • testdirectory/는 디렉토리이므로 파일로 간주되지 않습니다. Linux에서는 모든 것이 파일 디스크립터이지만, 편의를 위해 파이썬은 디렉토리를 다르게 처리합니다 (디렉토리를 열려고 하면 IsADirectoryError가 발생합니다).
  • i-dont-even-exist는 존재하지 않는 파일을 가리킵니다.

os.path.isdir()

디렉토리가 올바른 위치에 있는지 확인하려면, 주어진 경로가 디렉토리를 가리키는 경우에만 True를 반환하는 os.path.isdir() 함수를 사용해야 합니다.

In [1]: import os

In [2]: os.path.isdir('testfile.txt')
Out[2]: False

In [3]: os.path.isdir('testdirectory')
Out[3]: True

In [4]: os.path.isdir('anotherfile.txt')
Out[4]: False

경로가 존재하는 파일을 가리키더라도 위 예시에서 False를 반환하는 것에 주목하세요.

glob

glob 모듈은 유닉스 셸과 유사한 패턴을 처리하는 기능을 제공합니다(따라서 윈도우에서는 제대로 작동하지 않을 수 있습니다). 현재 디렉토리 내에서 특정 패턴과 일치하는 파일들을 확인하려면 glob.glob() 함수를 사용할 수 있습니다.

In [1]: import glob

In [2]: glob.glob('testfile.txt')
Out[2]: ['testfile.txt']

In [3]: glob.glob('testdirectory')
Out[3]: ['testdirectory']

위 코드에서 glob 함수에 전달된 패턴은 테스트 파일 및 디렉토리의 경로를 나타내는 일반적인 문자열입니다. 두 경로 모두 존재하므로 함수는 일치하는 경로 이름이 담긴 목록을 반환합니다.

참고: 패턴과 일치하는 항목이 없으면 빈 목록을 반환합니다.

glob 함수에 패턴을 전달할 수 있다는 점을 고려하여, 몇 가지 유용한 활용법을 확인해 보겠습니다.

다음 코드는 각각 .txt.py 확장자를 가진 모든 파일 경로를 가져옵니다.

In [4]: glob.glob('*.txt')
Out[4]: ['testfile.txt']

In [5]: glob.glob('*.py')
Out[5]:
['pathlib-exists.py',
 'list-dir.py',
 'glob-file.py',
 'open-except.py',
 'subprocess-test.py',
 'isfile.py',
 'exists.py',
 'isdir.py']

Path 클래스 사용

Path 클래스는 파일 경로를 객체로 다룰 수 있는 깔끔한 인터페이스를 제공하므로, 경로를 조작하는 데 매우 유용한 방법입니다.

Path 인스턴스에는 특정 경로에 대한 정보를 얻는 데 필요한 모든 메서드가 포함되어 있다는 것이 가장 큰 장점 중 하나입니다. 여기에는 이전 옵션들과 유사한 기능들도 포함되어 있습니다.

참고: pathlib 라이브러리를 사용하려면 파이썬 3.4 이상이 필요합니다.

사용 가능한 Path 메서드:

경로 존재 여부 확인

In [1]: from pathlib import Path

In [2]: Path('testfile.txt').exists()
Out[2]: True

In [3]: Path('im-not-here.txt').exists()
Out[3]: False

In [4]: Path('testdirectory').exists()
Out[4]: True

os.path.exists()와 동일하게 작동합니다.

경로가 파일을 가리키는지 확인

In [5]: Path('testfile.txt').is_file()
Out[5]: True

In [6]: Path('testdirectory').is_file()
Out[6]: False

os.path.isfile()과 동일합니다.

경로가 디렉토리를 가리키는지 확인

In [7]: Path('testfile.txt').is_dir()
Out[7]: False

In [8]: Path('testdirectory').is_dir()
Out[8]: True

os.path.isdir()에 해당합니다.

subprocess 모듈 활용

만약 하위 프로세스 모듈을 선호한다면 이 옵션에 대해 알아두어야 합니다. test 명령을 사용하여 파일 또는 폴더의 존재 여부를 확인할 수 있습니다.

참고: test 명령은 유닉스 계열 운영체제에서만 작동합니다.

다음 테스트 플래그를 사용하여 원하는 작업을 수행할 수 있습니다:

  • test -e: 경로가 존재하는지 확인
  • test -f: 파일이 존재하는지 확인
  • test -d: 폴더가 존재하는지 확인

더 많은 테스트 플래그에 대한 정보는 다음 명령을 실행하여 설명서를 읽어볼 수 있습니다.

man test

subprocess 모듈로 경로 확인

아래 코드는 하위 프로세스의 반환 코드를 0과 비교하여 경로의 존재 여부를 확인합니다.

리눅스에서는 프로세스가 성공적으로 완료되면 0을 반환하고, 실패하면 다른 코드를 반환한다는 것을 기억하세요.

In [1]: from subprocess import run

In [2]: run(['test', '-e', 'testfile.txt']).returncode == 0
Out[2]: True

In [3]: run(['test', '-e', 'im-not-here.txt']).returncode == 0
Out[3]: False

첫 번째 명령에서 subprocess 모듈을 가져온 다음 run 함수를 사용하여 반환 코드를 얻습니다.

subprocess 모듈로 파일 존재 확인

In [4]: run(['test', '-f', 'testfile.txt']).returncode == 0
Out[4]: True

In [5]: run(['test', '-f', 'testdirectory']).returncode == 0
Out[5]: False

subprocess 모듈로 디렉토리 확인

In [6]: run(['test', '-d', 'testfile.txt']).returncode == 0
Out[6]: False

In [7]: run(['test', '-d', 'testdirectory']).returncode == 0
Out[7]: True

이 방법은 리소스를 더 많이 소비하므로 사용하는 것을 권장하지 않습니다. 특별한 이점도 없습니다.

요약

파이썬은 운영체제와 상호작용하여 프로세스를 자동화하는 데 가장 널리 사용되는 프로그래밍 언어 중 하나입니다. 이러한 기능 중 하나는 파일이나 폴더의 존재 여부를 확인하는 것입니다.

가장 간단한 방법은 다음과 같습니다:

  • 파일을 열고 예외를 처리하는 것
  • os.path 또는 pathlib 모듈의 exists() 함수를 사용하는 것

이 튜토리얼을 통해 다음을 배웠습니다:

  • 파일이 존재하지 않을 때 파일을 열고 예외를 처리하는 방법
  • 경로의 의미
  • 파일 또는 폴더의 존재 여부를 확인하기 위해 os.path 하위 모듈에서 제공하는 3가지 함수
  • 유닉스에서는 슬래시(/)를, 윈도우에서는 백슬래시(\)를 사용하여 경로를 구분한다는 사실

다음 읽을거리: 파이썬에서 하위 프로세스란 무엇입니까? [5가지 사용 예]