How to get the current running module path/name
Question:
I’ve searched and this seems to be a simple question without a simple answer.
I have the file a/b/c.py
which would be called with python -m a.b.c
. I would like to obtain the value a.b.c
in the module level.
USAGE = u'''
Usage:
python -m %s -h
''' % (what_do_i_put_here,)
So when I receive the -h
option, I display the USAGE
without the need to actually write down the actual value in each and every script.
Do I really need to go through inspect
to get the desired value?
Thanks.
EDIT: As said, there are answers (I’ve searched), but not simple answers. Either use inspect
, use of traceback
, or manipulate __file__
and __package__
and do some substring to get the answer. But nothing as simple as if I had a class in the module, I could just use myClass.__module__
and I would get the answer I want. The use of __name__
is (unfortunately) useless as it’s always "__main__"
.
Also, this is in python 2.6 and I cannot use any other versions.
Answers:
When run with -m, sys.path[0]
contains the full path to the module. You could use that to build the name.
source: http://docs.python.org/using/cmdline.html#command-line
Another option may be the __package__
built in variable which is available within modules.
I think you’re actually looking for the __name__
special variable. From the Python documentation:
Within a module, the module’s name (as a string) is available as the value of the global variable __name__
.
If you run a file directly, this name will __main__
. However, if you’re in a module (as in the case where you’re using the -m flag, or any other import), it will be the complete name of the module.
The only way is to do path manipulation with os.getcwd(), os.path, file and whatnot, as you mentioned.
Actually, it could be a good patch to implement for optparse / argparse (which currently replace “%prog” in the usage string with os.path.basename(sys.argv[0]) — you are using optparse, right? — ), i.e. another special string like %module.
This works for me:
__loader__.fullname
Also if I do python -m b.c from a I get ‘b.c’ as expected.
Not entirely sure what the __loader__ attribute is so let me know if this is no good.
edit: It comes from PEP 302: http://www.python.org/dev/peps/pep-0302/
Interesting snippets from the link:
The load_module() method has a few responsibilities that it must
fulfill before it runs any code:
…
- It should add an __loader__ attribute to the module, set to the
loader object. This is mostly for introspection, but can be used
for importer-specific extras, for example getting data associated
with an importer.
So it looks like it should work fine in all cases.
you should hardcode a.b.c
in your help, if you distribute the package as such then that’s the way to call it regardless of where a
is located in the filesystem, as long as it’s on the PYTHONPATH it’ll be imported.
Number of options are there to get the path/name of the current module.
First be familiar with the use of __file__ in Python, Click here to see the usage.
It holds the name of currently loaded module.
Check/Try the following code, it will work on both Python2 & Python3.
» module_names.py
import os
print (__file__)
print (os.path.abspath(__file__))
print (os.path.realpath(__file__))
Output on MAC OS X:
MacBook-Pro-2:practice admin$ python module_names.py
module_names.py
/Users/admin/projects/Python/python-the-snake/practice/module_names.py
/Users/admin/projects/Python/python-the-snake/practice/module_names.py
So here we got the name of current module name and its absolute path.
Why does nobody mentioned the .__module__
?
When doing a self.__module__
you will get the module path.
You can also do this outside of the class:
Class A:
self.__module__ # gets module.filename
def get_module():
A.__module__ # also gets module.filename
One liner But OS dependent
it does not work in interpreter! since file is meaningless there in the interpreter and is not defined.
does not require os module to be imported.
modulename=__file__.split("\")[-1].split('.')[0]
Explanation:
X:applepythonabc.py | will output pythonabc.py
select the last element after splitting with slashes, then select the first element by splitting it with dot ‘.’. because first step gives module.py, second step gives ‘module’ only. __file__ is a unique variable and returns the filepath of current module.
Comment any flaws or has any other pitfalls.
I’ve searched and this seems to be a simple question without a simple answer.
I have the file a/b/c.py
which would be called with python -m a.b.c
. I would like to obtain the value a.b.c
in the module level.
USAGE = u'''
Usage:
python -m %s -h
''' % (what_do_i_put_here,)
So when I receive the -h
option, I display the USAGE
without the need to actually write down the actual value in each and every script.
Do I really need to go through inspect
to get the desired value?
Thanks.
EDIT: As said, there are answers (I’ve searched), but not simple answers. Either use inspect
, use of traceback
, or manipulate __file__
and __package__
and do some substring to get the answer. But nothing as simple as if I had a class in the module, I could just use myClass.__module__
and I would get the answer I want. The use of __name__
is (unfortunately) useless as it’s always "__main__"
.
Also, this is in python 2.6 and I cannot use any other versions.
When run with -m, sys.path[0]
contains the full path to the module. You could use that to build the name.
source: http://docs.python.org/using/cmdline.html#command-line
Another option may be the __package__
built in variable which is available within modules.
I think you’re actually looking for the __name__
special variable. From the Python documentation:
Within a module, the module’s name (as a string) is available as the value of the global variable
__name__
.
If you run a file directly, this name will __main__
. However, if you’re in a module (as in the case where you’re using the -m flag, or any other import), it will be the complete name of the module.
The only way is to do path manipulation with os.getcwd(), os.path, file and whatnot, as you mentioned.
Actually, it could be a good patch to implement for optparse / argparse (which currently replace “%prog” in the usage string with os.path.basename(sys.argv[0]) — you are using optparse, right? — ), i.e. another special string like %module.
This works for me:
__loader__.fullname
Also if I do python -m b.c from a I get ‘b.c’ as expected.
Not entirely sure what the __loader__ attribute is so let me know if this is no good.
edit: It comes from PEP 302: http://www.python.org/dev/peps/pep-0302/
Interesting snippets from the link:
The load_module() method has a few responsibilities that it must
fulfill before it runs any code:…
- It should add an __loader__ attribute to the module, set to the
loader object. This is mostly for introspection, but can be used
for importer-specific extras, for example getting data associated
with an importer.
So it looks like it should work fine in all cases.
you should hardcode a.b.c
in your help, if you distribute the package as such then that’s the way to call it regardless of where a
is located in the filesystem, as long as it’s on the PYTHONPATH it’ll be imported.
Number of options are there to get the path/name of the current module.
First be familiar with the use of __file__ in Python, Click here to see the usage.
It holds the name of currently loaded module.
Check/Try the following code, it will work on both Python2 & Python3.
» module_names.py
import os
print (__file__)
print (os.path.abspath(__file__))
print (os.path.realpath(__file__))
Output on MAC OS X:
MacBook-Pro-2:practice admin$ python module_names.py
module_names.py
/Users/admin/projects/Python/python-the-snake/practice/module_names.py
/Users/admin/projects/Python/python-the-snake/practice/module_names.py
So here we got the name of current module name and its absolute path.
Why does nobody mentioned the .__module__
?
When doing a self.__module__
you will get the module path.
You can also do this outside of the class:
Class A:
self.__module__ # gets module.filename
def get_module():
A.__module__ # also gets module.filename
One liner But OS dependent
it does not work in interpreter! since file is meaningless there in the interpreter and is not defined.
does not require os module to be imported.
modulename=__file__.split("\")[-1].split('.')[0]
Explanation:
X:applepythonabc.py | will output pythonabc.py
select the last element after splitting with slashes, then select the first element by splitting it with dot ‘.’. because first step gives module.py, second step gives ‘module’ only. __file__ is a unique variable and returns the filepath of current module.
Comment any flaws or has any other pitfalls.