I want to detect whether module has changed. Now, using inotify is simple, you just need to know the directory you want to get notifications from.
How do I retrieve a module's path in python?
I want to detect whether module has changed. Now, using inotify is simple, you just need to know the directory you want to get notifications from.
How do I retrieve a module's path in python?
If the only caveat of using
__file__
is when current, relative directory is blank (ie, when running as a script from the same directory where the script is), then a trivial solution is:And the result:
The trick is in
or '.'
after thedirname()
call. It sets the dir as.
, which means current directory and is a valid directory for any path-related function.Thus, using
abspath()
is not truly needed. But if you use it anyway, the trick is not needed:abspath()
accepts blank paths and properly interprets it as the current directory.If you would like to know absolute path from your script you can use Path object:
cwd() method
resolve() method
I don't get why no one is talking about this, but to me the simplest solution is using imp.find_module("modulename") (documentation here):
It gives a tuple with the path in second position:
The advantage of this method over the "inspect" one is that you don't need to import the module to make it work, and you can use a string in input. Useful when checking modules called in another script for example.
EDIT:
In python3,
importlib
module should do:Doc of
importlib.util.find_spec
:As the other answers have said, the best way to do this is with
__file__
(demonstrated again below). However, there is an important caveat, which is that__file__
does NOT exist if you are running the module on its own (i.e. as__main__
).For example, say you have two files (both of which are on your PYTHONPATH):
and
Running foo.py will give the output:
HOWEVER if you try to run bar.py on its own, you will get:
Hope this helps. This caveat cost me a lot of time and confusion while testing the other solutions presented.
If you wish to do this dynamically in a "program" try this code:
My point is, you may not know the exact name of the module to "hardcode" it. It may be selected from a list or may not be currently running to use __file__.
(I know, it will not work in Python 3)
I tried to get rid of the "global" issue but found cases where it did not work I think "execfile()" can be emulated in Python 3 Since this is in a program, it can easily be put in a method or module for reuse.
I'd like to contribute with one common scenario (in Python 3) and explore a few approaches to it.
The built-in function open() accepts either relative or absolute path as its first argument. The relative path is treated as relative to the current working directory though so it is recommended to pass the absolute path to the file.
Simply said, if you run a script file with the following code, it is not guaranteed that the
example.txt
file will be created in the same directory where the script file is located:To fix this code we need to get the path to the script and make it absolute. To ensure the path to be absolute we simply use the os.path.realpath() function. To get the path to the script there are several common functions that return various path results:
os.getcwd()
os.path.realpath('example.txt')
sys.argv[0]
__file__
Both functions os.getcwd() and os.path.realpath() return path results based on the current working directory. Generally not what we want. The first element of the sys.argv list is the path of the root script (the script you run) regardless of whether you call the list in the root script itself or in any of its modules. It might come handy in some situations. The __file__ variable contains path of the module from which it has been called.
The following code correctly creates a file
example.txt
in the same directory where the script is located: