Getting the location (path) of a running file in Python: __file__.

Money and Business

To get the location (path) of a running script file in Python, use __file__. This is useful for loading other files based on the location of the running file.

Up to Python 3.8, __file__ returns the path specified when executing the python command (or python3 command in some environments). If a relative path is specified, the relative path is returned; if an absolute path is specified, the absolute path is returned.

In Python 3.9 and later, the absolute path is returned regardless of the path specified at runtime.

The following contents are explained.

  • os.getcwd(),__file__
  • Get the file name and directory name of the currently executing file.
  • Get the absolute path of the file being executed.
  • Reads other files based on the location of the currently executing file.
  • Move the current directory to the directory of the file being executed.
  • The same processing can be done regardless of the current directory at runtime.

See the following article for information on getting and changing the current directory (working directory).

Note that __file__ cannot be used in Jupyter Notebook (.ipynb).
The directory where .ipynb is located will be executed as the current directory, regardless of the directory where Jupyter Notebook is started.
It is possible to use os.chdir() in the code to change the current directory.

os.getcwd() and __file__.

In Windows, you can use the dir command instead of pwd to check the current directory.

pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook

Create a Python script file (file_path.py) with the following contents in the lower level (data\src).

import os

print('getcwd:      ', os.getcwd())
print('__file__:    ', __file__)

Run the python command (or python3 command in some environments) specifying the path to the script file.

python3 data/src/file_path.py
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook
# __file__:     data/src/file_path.py

The absolute path to the current directory can be obtained with os.getcwd(). You can also use __file__ to get the path specified by the python3 command.

Up to Python 3.8, __file__ will contain the path specified in the python (or python3) command. In the example above, the relative path is returned because it is relative, but the absolute path is returned if it is absolute.

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 and later returns the absolute path to __file__, regardless of the path specified in the python (or python3) command.

In the following example, we will add the code to the same script file (file_path.py) in Python 3.7 and run it relative to the above directory.

In Python 3.7, the absolute path is used. The results are shown at the end of this section.

Get the file name and directory name of the currently executing file.

To get the file name and directory name of the running file, use the following function in the os.path module of the standard library.

  • os.path.basename()
  • os.path.dirname()
print('basename:    ', os.path.basename(__file__))
print('dirname:     ', os.path.dirname(__file__))

Execution result.

# basename:     file_path.py
# dirname:      data/src

Get the absolute path of the file being executed.

If a relative path is obtained with __file__, it can be converted to an absolute path with os.path.abspath(). Directories can also be obtained as absolute paths.

print('abspath:     ', os.path.abspath(__file__))
print('abs dirname: ', os.path.dirname(os.path.abspath(__file__)))

Execution result.

# 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

If an absolute path is specified in os.path.abspath(), it will be returned as is. Therefore, if __file__ is an absolute path, the following will not cause an error.

  • os.path.abspath(__file__)

Reads other files based on the location of the currently executing file.

If you want to read other files based on the location (path) of the file being executed, join the following two files using os.path.join().

  • Directory of the file being executed
  • Relative path to the file to be read from the running file.

If you want to read a file in the same directory as the file you are running, just concatenate the file name.

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())

Execution result.

# [set target path 1]
# target_path_1:  data/src/target_1.txt
# read target file:
# !! This is "target_1.txt" !!

The upper level is represented by “. \”. You can leave it as it is, but you can use os.path.normpath() to normalize the path and remove extra “. \” and other characters.

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())

Execution result.

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

Move the current directory to the directory of the file being executed.

Use os.chdir() to move the current directory to the directory of the file being executed in the script.

You can see that it is moved by os.getcwd().

print('[change directory]')
os.chdir(os.path.dirname(os.path.abspath(__file__)))
print('getcwd:      ', os.getcwd())

Execution result.

# [change directory]
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook/data/src

Once the current directory has been moved, there is no need to concatenate it with the directory of the running file when reading the file. You can just specify the path relative to the directory of the running file.

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())

Execution result.

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

The same processing can be done regardless of the current directory at runtime.

As we have shown, it is possible to load files based on the location of the script file, independent of the current directory at runtime, using one of the following methods.

  • Concatenate the directory of the running file and the relative path to the file to be read from the running file using os.path.join().
  • Move the current directory to the directory of the file being executed.

It is easier to move the current directory, but of course, if you want to read or write more files after that, you need to take into account that the current directory has been moved.

The results of the previous examples are summarized below.

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

The result of specifying the absolute path is as follows.

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

The result of moving the current directory in the terminal and executing the same script file is shown below. You can see that the same file can be read even if it is executed from a different location.

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

Copied title and URL