Get the path of the current file (script) in Python: __file__
In Python, you can use __file__
to get the path of the current file, i.e., the currently running script file (.py
). This is particularly useful when you need to read other files relative to the current file's location.
In Python 3.8 and earlier, __file__
returns the path specified when executing the python
(or python3
) command. If you specify a relative path, it is returned as such, and the same applies for an absolute path.
From Python 3.9 onwards, however, __file__
always returns an absolute path, whether you used a relative or an absolute path when executing the python
command.
__file__
stores the path of the current script file- Get the file and directory name of the current script file
- Get the absolute path of the current script file
- Read other files relative to the current file's location
- Change the current directory to the directory of the current script file
- Read the same file regardless of the current working directory
In the sample code in this article, assume that you are working in the following directory. On Windows, you can check the current directory with the dir
command instead of pwd
.
pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook
See the following article on how to get and change the current working directory in Python.
Note that __file__
is not available in Jupyter Notebook (.ipynb
). Regardless of where you started the Jupyter Notebook, the current directory is where the .ipynb
file is located. However, you can change the current directory by using os.chdir()
in your code.
__file__
stores the path of the current script file
Create a Python script file (file_path.py
) in the subdirectory (data/src
).
import os
print('getcwd: ', os.getcwd())
print('__file__: ', __file__)
Execute this file with the python
(or python3
) command.
python3 data/src/file_path.py
# getcwd: /Users/mbp/Documents/my-project/python-snippets/notebook
# __file__: data/src/file_path.py
You can get the absolute path of the current working directory using os.getcwd()
, and you can obtain the path specified with the python3
command using __file__
.
In Python 3.8 and earlier, __file__
stores the path specified when executing the python
(or python3
) command. In the above example, a relative path is specified, so it is returned; if specified as absolute, an absolute path would be returned.
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
In Python 3.9 and later, __file__
always stores an absolute path, regardless of whether the path specified with the python
command is relative or absolute.
In the following examples, add code to the same script file (file_path.py
) and execute it from the same directory as the above example, using Python 3.7.
Note that if __file__
is an absolute path (always the case with Python 3.9 or later, and when specifying the absolute path in Python 3.8 or earlier), you can use the same code below to read other files relative to the current script file location. The results of specifying the absolute path in Python 3.7 are shown at the end of this article.
Get the file and directory name of the current script file
You can use os.path.basename()
and os.path.dirname()
to get the file and directory name of the current script file.
import os
print('basename: ', os.path.basename(__file__))
print('dirname: ', os.path.dirname(__file__))
The result is as follows.
# basename: file_path.py
# dirname: data/src
If you want to get the name of the directory containing the current file (src
in the example above), use os.path.basename(os.path.dirname(__file__))
.
Get the absolute path of the current script file
If __file__
stores the relative path, you can convert it to an absolute path using os.path.abspath()
.
import os
print('abspath: ', os.path.abspath(__file__))
print('abs dirname: ', os.path.dirname(os.path.abspath(__file__)))
The result is as follows.
# 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
Note that os.path.abspath()
will simply return the same path if you give it an absolute path. So, even if __file__
is already an absolute path, using os.path.abspath(__file__)
will not raise an error.
Read other files relative to the current file's location
If you want to read other files relative to the current file's location, you can use os.path.join()
to combine the directory path of the current file and the relative path of the file you want to read.
If a file is in the same directory as the script file, you can read it by just specifying its name.
import os
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())
The result is as follows.
# [set target path 1]
# target_path_1: data/src/target_1.txt
# read target file:
# !! This is "target_1.txt" !!
In a file path, ../
represents the parent directory. Although the path will work as it is, you can use os.path.normpath()
to normalize the path and eliminate any unnecessary ../
segments.
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())
The result is as follows.
# [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" !!
Refer to the following article for more information on reading files.
Change the current directory to the directory of the current script file
You can use os.chdir()
to change the current working directory to the directory where the current script file is located.
You can then use os.getcwd()
to confirm the change.
import os
print('[change directory]')
os.chdir(os.path.dirname(os.path.abspath(__file__)))
print('getcwd: ', os.getcwd())
The result is as follows.
# [change directory]
# getcwd: /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
If the current working directory is the same as the directory of the current file, you can use a relative path from the current file to read other files.
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())
The result is as follows.
# [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" !!
Read the same file regardless of the current working directory
By using __file__
to obtain the path of the current script file, you can consistently read the same file, regardless of the current working directory.
As shown so far, there are two ways to do this:
- Join the
__file__
directory and the relative path (from__file__
) of the file you want to read withos.path.join()
. - Change the current working directory to the
__file__
directory.
While it is simpler to change the current directory, any subsequent file reading or writing operations should take into account that the current directory has been changed.
The results of the examples so far are as follows.
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 results when specifying the absolute path with the python3
command are as follows. As you can see, you can read the same file:
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" !!
Change the current directory in the terminal and execute the same script file, and you can see that the same file is read, even though the current directory is different.
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" !!