Python에서 실행 중인 스크립트 파일의 위치(경로)를 얻으려면 __file__을 사용합니다. 이것은 실행 중인 파일의 위치를 기반으로 다른 파일을 로드할 때 유용합니다.
Python 3.8까지 __file__은 python 명령(또는 일부 환경에서는 python3 명령)을 실행할 때 지정된 경로를 반환합니다. 상대 경로가 지정되면 상대 경로가 반환됩니다. 절대 경로가 지정되면 절대 경로가 반환됩니다.
Python 3.9 이상에서는 런타임에 지정된 경로에 관계없이 절대 경로가 반환됩니다.
다음 내용을 설명합니다.
os.getcwd()
,__file__
- 현재 실행 중인 파일의 파일 이름과 디렉터리 이름을 가져옵니다.
- 실행 중인 파일의 절대 경로를 가져옵니다.
- 현재 실행 중인 파일의 위치를 기준으로 다른 파일을 읽습니다.
- 현재 디렉터리를 실행 중인 파일의 디렉터리로 이동합니다.
- 런타임 시 현재 디렉토리에 관계없이 동일한 처리를 수행할 수 있습니다.
현재 디렉토리(작업 디렉토리) 가져오기 및 변경에 대한 정보는 다음 문서를 참조하십시오.
__file__은 Jupyter Notebook(.ipynb)에서 사용할 수 없습니다.
.ipynb가 있는 디렉토리는 Jupyter Notebook이 시작된 디렉토리와 상관없이 현재 디렉토리로 실행됩니다.
코드에서 os.chdir()을 사용하여 현재 디렉토리를 변경할 수 있습니다.
os.getcwd() 및 __file__.
Windows에서는 pwd 대신 dir 명령을 사용하여 현재 디렉터리를 확인할 수 있습니다.
pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook
하위 수준(data\src)에 다음 내용으로 Python 스크립트 파일(file_path.py)을 만듭니다.
import os
print('getcwd: ', os.getcwd())
print('__file__: ', __file__)
스크립트 파일의 경로를 지정하여 python 명령(또는 일부 환경에서는 python3 명령)을 실행합니다.
python3 data/src/file_path.py
# getcwd: /Users/mbp/Documents/my-project/python-snippets/notebook
# __file__: data/src/file_path.py
현재 디렉토리의 절대 경로는 os.getcwd()로 얻을 수 있습니다. __file__을 사용하여 python3 명령으로 지정된 경로를 가져올 수도 있습니다.
Python 3.8까지 __file__에는 python(또는 python3) 명령에 지정된 경로가 포함됩니다. 위의 예에서 상대 경로는 상대 경로이므로 반환되지만 절대 경로이면 절대 경로가 반환됩니다.
pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook
python3 /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# getcwd: /Users/mbp/Documents/my-project/python-snippets/notebook
# __file__: /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
Python 3.9 이상은 python(또는 python3) 명령에 지정된 경로에 관계없이 __file__에 대한 절대 경로를 반환합니다.
다음 예제에서는 Python 3.7의 동일한 스크립트 파일(file_path.py)에 코드를 추가하고 위의 디렉터리를 기준으로 실행합니다.
Python 3.7에서는 절대 경로가 사용됩니다. 결과는 이 섹션의 끝에 표시됩니다.
현재 실행 중인 파일의 파일 이름과 디렉터리 이름을 가져옵니다.
실행 중인 파일의 파일 이름과 디렉토리 이름을 얻으려면 표준 라이브러리의 os.path 모듈에서 다음 함수를 사용하십시오.
os.path.basename()
os.path.dirname()
print('basename: ', os.path.basename(__file__))
print('dirname: ', os.path.dirname(__file__))
실행 결과입니다.
# basename: file_path.py
# dirname: data/src
실행 중인 파일의 절대 경로를 가져옵니다.
__file__을 사용하여 상대 경로를 얻은 경우 os.path.abspath()를 사용하여 절대 경로로 변환할 수 있습니다. 디렉토리는 절대 경로로도 얻을 수 있습니다.
print('abspath: ', os.path.abspath(__file__))
print('abs dirname: ', os.path.dirname(os.path.abspath(__file__)))
실행 결과입니다.
# abspath: /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# abs dirname: /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
os.path.abspath()에 절대 경로가 지정되면 그대로 반환됩니다. 따라서 __file__이 절대 경로인 경우 다음과 같이 해도 오류가 발생하지 않습니다.
os.path.abspath(__file__)
현재 실행 중인 파일의 위치를 기준으로 다른 파일을 읽습니다.
실행 중인 파일의 위치(경로)를 기준으로 다른 파일을 읽으려면 os.path.join()을 사용하여 다음 두 파일을 결합하십시오.
- 실행 중인 파일의 디렉토리
- 실행 중인 파일에서 읽을 파일의 상대 경로입니다.
실행 중인 파일과 동일한 디렉토리에 있는 파일을 읽으려면 파일 이름을 연결하면 됩니다.
print('[set target path 1]')
target_path_1 = os.path.join(os.path.dirname(__file__), 'target_1.txt')
print('target_path_1: ', target_path_1)
print('read target file:')
with open(target_path_1) as f:
print(f.read())
실행 결과입니다.
# [set target path 1]
# target_path_1: data/src/target_1.txt
# read target file:
# !! This is "target_1.txt" !!
상위 레벨은 “. \”로 표시됩니다. 그대로 둘 수 있지만 os.path.normpath()를 사용하여 경로를 정규화하고 추가 “.\” 및 기타 문자를 제거할 수 있습니다.
print('[set target path 2]')
target_path_2 = os.path.join(os.path.dirname(__file__), '../dst/target_2.txt')
print('target_path_2: ', target_path_2)
print('normalize : ', os.path.normpath(target_path_2))
print('read target file:')
with open(target_path_2) as f:
print(f.read())
실행 결과입니다.
# [set target path 2]
# target_path_2: data/src/../dst/target_2.txt
# normalize : data/dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!
현재 디렉터리를 실행 중인 파일의 디렉터리로 이동합니다.
os.chdir()을 사용하여 현재 디렉터리를 스크립트에서 실행 중인 파일의 디렉터리로 이동합니다.
os.getcwd()에 의해 이동된 것을 볼 수 있습니다.
print('[change directory]')
os.chdir(os.path.dirname(os.path.abspath(__file__)))
print('getcwd: ', os.getcwd())
실행 결과입니다.
# [change directory]
# getcwd: /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
현재 디렉토리가 이동되면 파일을 읽을 때 실행 중인 파일의 디렉토리와 연결할 필요가 없습니다. 실행 중인 파일의 디렉토리에 상대적인 경로를 지정할 수 있습니다.
print('[set target path 1 (after chdir)]')
target_path_1 = 'target_1.txt'
print('target_path_1: ', target_path_1)
print('read target file:')
with open(target_path_1) as f:
print(f.read())
print()
print('[set target path 2 (after chdir)]')
target_path_2 = '../dst/target_2.txt'
print('target_path_2: ', target_path_2)
print('read target file:')
with open(target_path_2) as f:
print(f.read())
실행 결과입니다.
# [set target path 1 (after chdir)]
# target_path_1: target_1.txt
# read target file:
# !! This is "target_1.txt" !!
#
# [set target path 2 (after chdir)]
# target_path_2: ../dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!
런타임 시 현재 디렉토리에 관계없이 동일한 처리를 수행할 수 있습니다.
우리가 보여준 것처럼 다음 방법 중 하나를 사용하여 런타임 시 현재 디렉토리와 상관없이 스크립트 파일의 위치를 기반으로 파일을 로드할 수 있습니다.
- os.path.join()을 사용하여 실행 중인 파일의 디렉터리와 실행 중인 파일에서 읽을 파일의 상대 경로를 연결합니다.
- 현재 디렉터리를 실행 중인 파일의 디렉터리로 이동합니다.
현재 디렉토리를 이동하는 것이 더 쉽지만, 물론 그 이후에 더 많은 파일을 읽거나 쓰고 싶다면 현재 디렉토리가 이동되었다는 점을 고려해야 합니다.
이전 예의 결과는 아래에 요약되어 있습니다.
pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook
python3 data/src/file_path.py
# getcwd: /Users/mbp/Documents/my-project/python-snippets/notebook
# __file__: data/src/file_path.py
# basename: file_path.py
# dirname: data/src
# abspath: /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# abs dirname: /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
#
# [set target path 1]
# target_path_1: data/src/target_1.txt
# read target file:
# !! This is "target_1.txt" !!
#
# [set target path 2]
# target_path_2: data/src/../dst/target_2.txt
# normalize : data/dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!
#
# [change directory]
# getcwd: /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
#
# [set target path 1 (after chdir)]
# target_path_1: target_1.txt
# read target file:
# !! This is "target_1.txt" !!
#
# [set target path 2 (after chdir)]
# target_path_2: ../dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!
절대 경로를 지정한 결과는 다음과 같습니다.
pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook
python3 /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# getcwd: /Users/mbp/Documents/my-project/python-snippets/notebook
# __file__: /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# basename: file_path.py
# dirname: /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# abspath: /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# abs dirname: /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
#
# [set target path 1]
# target_path_1: /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/target_1.txt
# read target file:
# !! This is "target_1.txt" !!
#
# [set target path 2]
# target_path_2: /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/../dst/target_2.txt
# normalize : /Users/mbp/Documents/my-project/python-snippets/notebook/data/dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!
#
# [change directory]
# getcwd: /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
#
# [set target path 1 (after chdir)]
# target_path_1: target_1.txt
# read target file:
# !! This is "target_1.txt" !!
#
# [set target path 2 (after chdir)]
# target_path_2: ../dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!
터미널에서 현재 디렉토리를 이동하고 동일한 스크립트 파일을 실행한 결과는 아래와 같다. 다른 위치에서 실행되어도 동일한 파일을 읽을 수 있음을 알 수 있습니다.
cd data/src
pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
python3 file_path.py
# getcwd: /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# __file__: file_path.py
# basename: file_path.py
# dirname:
# abspath: /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# abs dirname: /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
#
# [set target path 1]
# target_path_1: target_1.txt
# read target file:
# !! This is "target_1.txt" !!
#
# [set target path 2]
# target_path_2: ../dst/target_2.txt
# normalize : ../dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!
#
# [change directory]
# getcwd: /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
#
# [set target path 1 (after chdir)]
# target_path_1: target_1.txt
# read target file:
# !! This is "target_1.txt" !!
#
# [set target path 2 (after chdir)]
# target_path_2: ../dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!