Python에서 실행 중인 파일의 위치(경로) 얻기: __file__.

사업

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" !!