HOWTO
파이썬에서 현재 스크립트 파일 디렉토리를 얻는 방법
현재 스크립트 파일의 경로를 얻는 방법에 대한 코드 예제를 제공합니다.
이 페이지의 내용
실행 중인 Python 스크립트가 들어 있는 디렉터리를 얻으려면 os.path.dirname(os.path.abspath(__file__)) 또는 Path(__file__).resolve().parent를 사용합니다. 두 표현 모두 스크립트 경로인 __file__에서 시작해 스크립트가 들어 있는 디렉터리를 구합니다. 이 디렉터리를 기준으로 스크립트와 같은 위치에 저장된 파일의 경로를 만들 수 있습니다.
현재 스크립트가 들어 있는 디렉터리 구하기
스크립트 디렉터리는 .py 파일이 들어 있는 폴더입니다. __file__에는 스크립트 경로가 들어 있습니다. 여기에 os.path.abspath()를 적용한 뒤 os.path.dirname()을 적용하면 절대 디렉터리 경로를 얻습니다. 스크립트 가까이에 있는 설정 파일, 입력 파일 또는 데이터 파일을 사용할 때 유용합니다. __file__가 상대 경로라면 os.path.abspath()는 프로세스의 작업 디렉토리를 기준으로 경로를 해석하므로, 결과가 Python을 실행한 위치에 따라 달라질 수 있습니다. __file__가 이미 절대 경로라면 작업 디렉토리는 그 위치를 결정하지 않습니다.
저장된 Python 파일에서 다음 예제를 실행하세요.
이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.
import os
script_path = os.path.abspath(__file__)
script_directory = os.path.dirname(script_path)
directory, filename = os.path.split(script_path)
print("Script directory:", script_directory)
print("Directory and filename:", directory, filename)
Script directory: /work
Directory and filename: /work case-0.py
os.path.abspath()는 현재 프로세스 환경을 기준으로 스크립트 경로를 절대 경로로 만들고, os.path.dirname()은 경로에서 디렉터리 부분을 가져옵니다. os.path.split()은 디렉터리와 파일 이름을 별도의 값으로 반환합니다. 출력되는 디렉터리는 파일을 저장한 위치에 따라 달라지므로, 어디서나 동일한 출력 경로는 없습니다.
스크립트 디렉터리와 작업 디렉토리 구분하기
작업 디렉토리는 open("data.csv")와 같은 상대 경로를 해석할 때 프로세스가 기준으로 삼는 위치입니다. os.getcwd()로 확인할 수 있습니다. 터미널의 현재 폴더, IDE 설정 또는 부모 프로세스가 선택한 디렉터리일 수 있으며, 스크립트가 들어 있는 폴더와 반드시 같지는 않습니다.
반면 __file__는 실행 중인 Python 파일의 경로를 나타냅니다. 예를 들어 /projects/tool에 있는 스크립트를 작업 디렉토리가 /tmp인 상태에서 실행하면, 상대 경로 data.csv는 /tmp를 기준으로 열립니다. 스크립트 디렉터리를 기준으로 만든 경로는 /projects/tool을 가리킵니다. 파일이 있어야 할 위치에 맞춰 기준 경로를 선택하세요. 스크립트와 같은 폴더에 있는 파일을 사용하려면 os.path.join(script_directory, "data.csv")로 파일 이름을 스크립트 디렉터리에 결합합니다.
__file__의 값이 상대 경로인지 절대 경로인지에 따라 절대 경로의 기준이 달라질 수 있습니다. 또한 이 값으로 만든 절대 경로가 파일의 존재를 보장하거나 모든 심볼릭 링크 및 배포 관련 문제를 해결해 주는 것은 아닙니다. 이 경로는 기준 위치를 나타낼 뿐이므로, 애플리케이션의 필요에 따라 결과 경로를 확인하거나 파일을 여세요.
os.path로 스크립트 디렉터리 구하기
앞의 예제에서는 각 작업을 명확히 보여 주기 위해 중간 값을 유지했습니다. 스크립트가 들어 있는 디렉터리만 필요하다면 os.path.dirname(os.path.abspath(__file__))처럼 호출을 결합할 수 있습니다. 디렉터리와 파일 이름이 모두 필요하다면 파일 이름을 버리지 말고 os.path.split()의 결과를 사용하세요.
같은 폴더에 있는 파일의 경로를 만들 때는 문자열에 슬래시를 이어 붙이는 대신 os.path.join()을 사용하세요. 그러면 Python이 플랫폼에 맞는 경로 구분자를 적용합니다. 예를 들어 os.path.join(script_directory, "settings.json")은 스크립트 디렉터리를 기준으로 경로를 만듭니다. 반면 open()에 상대 파일 이름을 직접 전달하면 작업 디렉토리를 기준으로 경로가 해석됩니다.
pathlib로 스크립트 디렉터리 구하기
pathlib을 사용하면 경로 객체로 같은 작업을 표현할 수 있습니다. 저장된 스크립트에서 Path(__file__).resolve().parent는 스크립트가 들어 있는 디렉터리입니다. resolve()는 경로를 해석해 절대 경로를 얻고, .parent는 그 경로의 부모 폴더를 선택합니다. /를 사용해 하위 경로를 추가할 수 있습니다. 예를 들어 script_directory / "settings.json"을 만들고, 그 결과인 Path 객체를 open()을 비롯해 경로형 객체를 받는 API에 전달하면 됩니다.
이에 해당하는 표현은 Path(__file__).resolve().parent입니다. 사용하기 전에 pathlib에서 Path를 가져오세요. 주변 코드가 이미 Path 객체를 사용한다면 pathlib을, 문자열 경로나 문자열을 요구하는 기존 API를 사용한다면 os.path를 선택하세요. 어느 방법도 프로세스의 작업 디렉토리를 바꾸지는 않습니다.
노트북 및 기타 실행 환경 다루기
Python이 저장된 스크립트를 실행할 때는 보통 __file__가 정의되지만, 대화형 인터프리터나 노트북 커널에서는 정의되지 않을 수 있습니다. 이런 환경에서는 위의 스크립트 기반 표현식으로 노트북 파일의 경로를 이식성 있게 알아낼 수 없습니다. os.getcwd()는 여전히 프로세스의 작업 디렉토리를 반환하므로 커널의 현재 위치를 기준으로 파일을 찾는 데 도움이 될 수 있지만, 노트북 소스 파일의 경로를 대신하지는 않습니다.
실행 중인 스크립트가 아닌 파일을 대상으로 한다면 __file__ 대신 그 파일의 알려진 경로에서 시작한 다음, os.path.dirname() 또는 Path 객체의 .parent를 사용해 디렉터리를 구하세요. 경로의 출처를 분명히 해 두면 나중에 읽는 사람도 그 경로가 스크립트, 다른 파일 또는 프로세스의 작업 디렉토리 중 무엇을 나타내는지 알 수 있습니다.