Reputation: 3930
Under certain circumstances, the variable __file__
is relative (see this stackoverflow question for details). If the variable is relative and one changes the current working directory, __file__
doesn't change accordingly. As a result, the relative path is invalid.
Please see this minimal example:
import os
if __name__ == '__main__':
filepath = __file__
filepath_real = os.path.realpath(filepath)
print('pwd', os.getcwd())
print('relative', filepath, os.path.exists(filepath))
print('absolute', filepath_real, os.path.exists(filepath_real))
os.chdir('..')
print('... changing the working directory ...')
filepath = __file__
filepath_real = os.path.realpath(filepath)
print('pwd', os.getcwd())
print('relative', filepath, os.path.exists(filepath))
print('absolute', filepath_real, os.path.exists(filepath_real))
Suppose this file is located at /home/user/project/script.py
. If I execute script.py
, this is the output:
$ cd /home/user/project/
$ python script.py
pwd /home/user/project
relative test.py True
absolute /home/user/project/test.py True
... changing the working directory ...
pwd /home/user
relative test.py False
absolute /home/user/test.py False
Is it possible to get a correct __file__
path (one that exists according to os.path.exists
) after changing the working directory in Python 3.7? I am aware that this issue does not exist in higher Python versions (such as 3.9), where __file__
always returns an absolute path.
Upvotes: 1
Views: 1726
Reputation: 568
get the __file__
path at the beginning of the python file, which ensure that you get the path when the file is imported before you calling the function.
python interpreter evaluate the file line by line in sequence, file will be evaulated only once by interpreter even you import the file multiple times , so first time the file is imported, all codes of the file have been evaluated and you path vallue is assigned.
you will only have issue when you change working dir, then force reload the file programmatically and reimport the file, then the value will be changed, otherwise it stays constant duing life time of your program.
EDIT
below example to show the after you import the module, the __file__
does not change after you change the working dir
import os
if __name__ == '__main__':
filepath = os.__file__
filepath_real = os.path.realpath(filepath)
print('pwd', os.getcwd())
print('relative', filepath, os.path.exists(filepath))
print('absolute', filepath_real, os.path.exists(filepath_real))
os.chdir('..')
print('... changing the working directory ...')
filepath = os.__file__
filepath_real = os.path.realpath(filepath)
print('pwd', os.getcwd())
print('relative', filepath, os.path.exists(filepath))
print('absolute', filepath_real, os.path.exists(filepath_real))
output
pwd /home/gftea/repo/jackygao/eiffel-system/utils
relative /usr/lib/python3.8/os.py True
absolute /usr/lib/python3.8/os.py True
... changing the working directory ...
pwd /home/gftea/repo/jackygao/eiffel-system
relative /usr/lib/python3.8/os.py True
absolute /usr/lib/python3.8/os.py True
Upvotes: 0