what does the __file__ variable mean/do?

Python

Python Problem Overview


import os

A = os.path.join(os.path.dirname(__file__), '..')

B = os.path.dirname(os.path.realpath(__file__))

C = os.path.abspath(os.path.dirname(__file__))

I usually just hard-wire these with the actual path. But there is a reason for these statements that determine path at runtime, and I would really like to understand the os.path module so that I can start using it.

Python Solutions


Solution 1 - Python

When a module is loaded from a file in Python, __file__ is set to its path. You can then use that with other functions to find the directory that the file is located in.

Taking your examples one at a time:

A = os.path.join(os.path.dirname(__file__), '..')
# A is the parent directory of the directory where program resides.

B = os.path.dirname(os.path.realpath(__file__))
# B is the canonicalised (?) directory where the program resides.

C = os.path.abspath(os.path.dirname(__file__))
# C is the absolute path of the directory where the program resides.

You can see the various values returned from these here:

import os
print(__file__)
print(os.path.join(os.path.dirname(__file__), '..'))
print(os.path.dirname(os.path.realpath(__file__)))
print(os.path.abspath(os.path.dirname(__file__)))

and make sure you run it from different locations (such as ./text.py, ~/python/text.py and so forth) to see what difference that makes.

Solution 2 - Python

I just want to address some confusion first. __file__ is not a wildcard it is an attribute. Double underscore attributes and methods are considered to be "special" by convention and serve a special purpose.

http://docs.python.org/reference/datamodel.html shows many of the special methods and attributes, if not all of them.

In this case __file__ is an attribute of a module (a module object). In Python a .py file is a module. So import amodule will have an attribute of __file__ which means different things under difference circumstances.

Taken from the docs:

> __file__ is the pathname of the file from which the module was loaded, if it was loaded from a file. The __file__ attribute is not present > for C modules that are statically linked into the interpreter; for > extension modules loaded dynamically from a shared library, it is the > pathname of the shared library file.

In your case the module is accessing it's own __file__ attribute in the global namespace.

To see this in action try:

# file: test.py

print globals()
print __file__

And run:

python test.py

{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__file__':
 'test_print__file__.py', '__doc__': None, '__package__': None}
test_print__file__.py

Solution 3 - Python

Per the documentation:

> __file__ is the pathname of the file from which the module was > loaded, if it was loaded from a file. The __file__ attribute is not > present for C modules that are statically linked into the interpreter; > for extension modules loaded dynamically from a shared library, it is > the pathname of the shared library file.

and also:

> __file__ is to be the “path” to the file unless the module is built-in (and thus listed in sys.builtin_module_names) in which case the attribute is not set.

Solution 4 - Python

Just going to add a quick note here (mostly answering the question's title rather than its description) about a change which can confuse some people. As of Python 3.4 there has been a slight change in how the __file__ behaves:

  • It's set to the relative path of the module in which it's used, if that module is executed directly.
  • It's set to the absolute path of the file otherwise.

> Module __file__ attributes (and related values) should now always contain absolute paths by default, with the sole exception of __main__.__file__ when a script has been executed directly using a relative path. (Contributed by Brett Cannon in issue 18416.)

Example:

Calling module x directly and module y indirectly:

# x.py:
from pathlib import Path
import y
print(__file__)
print(Path(__file__))
print(Path(__file__).resolve())

# y.py:
from pathlib import Path
print(__file__)
print(Path(__file__))

Running python3 x.py will output:

/home/aderchox/mytest/y.py                                                                                                                       
/home/aderchox/mytest/y.py                                                                                                                       
x.py                                                                                                                                             
x.py                                                                                                                                             
/home/aderchox/mytest/x.py

Solution 5 - Python

Using __file__ combined with various os.path modules lets all paths be relative the current module's directory location. This allows your modules/projects to be portable to other machines.

In your project you do:

A = '/Users/myname/Projects/mydevproject/somefile.txt'

and then try to deploy it to your server with a deployments directory like /home/web/mydevproject/ then your code won't be able to find the paths correctly.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiondeplingView Question on Stackoverflow
Solution 1 - PythonpaxdiabloView Answer on Stackoverflow
Solution 2 - PythonDerek LitzView Answer on Stackoverflow
Solution 3 - PythonSudhir BastakotiView Answer on Stackoverflow
Solution 4 - PythonaderchoxView Answer on Stackoverflow
Solution 5 - PythonSam DolanView Answer on Stackoverflow