如何获取当前运行模块的路径/名称
我搜索了一下,这似乎是个简单的问题,但没有简单的答案。
我有一个文件 a/b/c.py
,它是通过 python -m a.b.c
来调用的。我想在模块级别获取值 a.b.c
。
USAGE = u'''\
Usage:
python -m %s -h
''' % (what_do_i_put_here,)
所以当我收到 -h
这个选项时,我可以显示 USAGE
,而不需要在每个脚本里都写下实际的值。
我真的需要用 inspect
来获取这个值吗?
谢谢。
编辑:如我所说,虽然有一些答案(我查过了),但都不简单。要么使用 inspect
,要么使用 traceback
,或者操作 __file__
和 __package__
,然后做一些字符串处理来得到答案。但没有什么像我在模块里有个类时,可以直接用 myClass.__module__
就能得到我想要的答案那么简单。使用 __name__
是没用的,因为它总是显示 "__main__"
。
另外,这个是在 Python 2.6 中,我不能使用其他版本。
8 个回答
当使用 -m 选项运行时,sys.path[0]
会包含模块的完整路径。你可以利用这个路径来构建模块的名称。
来源: http://docs.python.org/using/cmdline.html#command-line
另一个选择是可以在模块中使用的内置变量 __package__
。
我觉得你其实是在寻找一个叫做 __name__
的特殊变量。根据Python文档的说法:
在一个模块内部,模块的名字(以字符串形式)可以通过全局变量
__name__
来获取。
如果你直接运行一个文件,这个名字会是 __main__
。但是,如果你在一个模块里面(比如使用了 -m 这个标志,或者其他的导入方式),它就会是模块的完整名称。
这个对我来说有效:
__loader__.fullname
另外,如果我从 a\ 目录运行 python -m b.c,结果也会得到 'b.c',这正是我期待的。
我对 __loader__ 这个属性不是很确定,如果有什么问题请告诉我。
编辑:这个属性来源于 PEP 302:http://www.python.org/dev/peps/pep-0302/
从这个链接中有一些有趣的内容:
load_module() 方法在运行任何代码之前,有几个责任需要完成:
...
- 它应该给模块添加一个 __loader__ 属性,并将其设置为加载器对象。这个主要是为了方便查看,但也可以用于特定于导入器的额外功能,比如获取与导入器相关的数据。
所以看起来在所有情况下它都应该能正常工作。