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.
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.
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.
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.
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.
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.
Can't see why there is such a restriction as "python -m a.b.c". Of course, the actual module could be inside some zip or whatever, but I'd rather simplified the whole approach with a wrapper script, which makes sure execution happens in the right context, with right python instance.
The wrapper can contain as little as:
import sys
__import__(sys.argv[1])
Then you can use your favorite method to get the module name for usage.
back to the original requirement. If I understood correctly, the idea is that someone runs a python file in some sub-sub-directory to find out from usage message that it is really a module of some.mega.package.
I think, there is no reliable, generic way to determine if one wants to run c, b.c or a.b.c module, without some file system analysis with certain heuristics (say, finding all __init__.py in the outer directories till the points there are no more __init__.py), and even with the analysis its not 100%.
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
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.
来源:https://stackoverflow.com/questions/5183601/how-to-get-the-current-running-module-path-name