How to get the current running module path/name

天大地大妈咪最大 提交于 2019-12-03 06:38:11

问题


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.


回答1:


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.




回答2:


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.




回答3:


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.




回答4:


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.




回答5:


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.




回答6:


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%.




回答7:


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



回答8:


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!