【问题标题】:How to get the current running module path/name如何获取当前正在运行的模块路径/名称
【发布时间】:2011-07-08 04:52:53
【问题描述】:

我已经搜索过了,这似乎是一个没有简单答案的简单问题。

我有文件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 中,我不能使用任何其他版本。

【问题讨论】:

标签: python python-2.6


【解决方案1】:

这对我有用:

__loader__.fullname

另外,如果我从 a\ 执行 python -m b.c,我会按预期得到 'b.c'。

不完全确定 __loader__ 属性是什么,如果不好请告诉我。

编辑:来自 PEP 302:http://www.python.org/dev/peps/pep-0302/

来自链接的有趣的sn-ps:

load_module() 方法有一些它必须的职责 完成 before 它运行任何代码:

...

  • 它应该向模块添加一个 __loader__ 属性,设置为 加载器对象。这主要用于自省,但可以使用 对于特定于进口商的附加功能,例如获取相关数据 与进口商合作。

所以看起来它应该在所有情况下都能正常工作。

【讨论】:

【解决方案2】:

我认为您实际上是在寻找 __name__ 特殊变量。来自Python documentation

在模块中,模块的名称(作为字符串)可用作全局变量 __name__ 的值。

如果你直接运行一个文件,这个名字将是__main__。但是,如果您在一个模块中(如您使用 -m 标志或任何其他导入的情况),它将是模块的完整名称。

【讨论】:

  • __name__ 如果使用“-m”标志调用它将是“main”。
  • 如果您想在 cmd 或终端中不使用 -m 选项获取更多 Pythonic 方式来获取模块名称,或者不想使用 loader,您可能有兴趣在下面某处查看我的答案。它是一个单行,使用字符串操作。问候。
【解决方案3】:

使用 -m 运行时,sys.path[0] 包含模块的完整路径。您可以使用它来建立名称。

来源:http://docs.python.org/using/cmdline.html#command-line

另一个选项可能是模块中可用的__package__ 内置变量。

【讨论】:

  • 感谢我编辑了我的问题,以指定我知道如何操作以获得答案,我希望有一种更简单的方法,而无需自己验证。
  • 你的意思是sys.argv[0]
【解决方案4】:

有许多选项可以获取当前模块的路径/名称。

首先熟悉__file__在Python中的使用,Click here to see the usage

它包含当前加载的模块的名称。

检查/尝试以下代码,它适用于 Python2Python3

» module_names.py

import os

print (__file__)
print (os.path.abspath(__file__))
print (os.path.realpath(__file__))

输出在 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

所以这里我们得到了当前模块名称的名称和它的绝对路径

【讨论】:

    【解决方案5】:

    正如你所提到的,唯一的方法是使用 os.getcwd()、os.path、file 等进行路径操作。

    实际上,它可能是一个很好的补丁来实现 optparse / argparse(目前将使用字符串中的“%prog”替换为 os.path.basename(sys.argv[0]) - 你是 使用 optparse,对吗?--),即另一个特殊字符串,如 %module。

    【讨论】:

    • 我实际上仍在使用仍然使用 getopt 的公司包。模块是在 2006-2007 年创建的?
    【解决方案6】:

    一个班轮,但取决于操作系统

    它在解释器中不起作用!因为 file 在解释器中是没有意义的并且没有被定义。

    不需要导入os模块。

    modulename=__file__.split("\\")[-1].split('.')[0]
    

    说明: X:\apple\pythonabc.py |将输出 pythonabc.py

    用斜线分割后选择最后一个元素,然后用点'.'分割它来选择第一个元素。因为第一步给出了module.py,第二步只给出了“模块”。 __file__ 是唯一变量,返回当前模块的文件路径。

    评论任何缺陷或有任何其他缺陷。

    【讨论】:

    • 能否请您删除指向您自己答案的其他答案上的 cmets?这样做会浪费别人的时间,而且很粗鲁。如果你的答案是好的,它会上升到顶部;如果不是,那么您就是在宣传一个错误的答案。
    • 您是否尝试过在问题一开始给出的示例路径/文件和python 命令?
    • python -m test 给了test,但test.b.c 没有成功。部分回答了 OP 的问题。如果有人通过谷歌偶然发现这里,他们可能会有其他想法。有很多方法可以解决问题。有时简单不是解决方案。
    • 它甚至没有部分回答,因为 OP 想要模块名称和Python filenames are not module names
    【解决方案7】:

    你应该在你的帮助中硬编码a.b.c,如果你这样分发包,那么不管a在文件系统中的什么位置,只要它在PYTHONPATH上,它就是调用它的方式进口的。

    【讨论】:

    • 这违背了我需要的目的。硬编码的问题总是如果我更改文件名,我需要记住更改帮助文本。
    • 如果您更改文件名,所有导入都将中断,因此帮助文本是您遇到的问题中较少的问题。
    • 脚本为入口点,其他模块不导入,不存在此问题。
    • 这与您的原始问题相矛盾,事实上,如果是这种情况,__name__ == "__main__" 照常工作。
    • 很抱歉不同意。我看不出更改当前文件的名称将如何破坏其中的导入。我已经开发了 5 年,并且更改入口点(脚本)的名称从未破坏其中的任何导入。如果你有具体的例子,请赐教。如果您指的是“相对”进口,我从不使用它们。
    【解决方案8】:

    为什么没有人提到.__module__

    执行self.__module__ 时,您将获得模块路径。 你也可以在课堂外这样做:

    Class A:
       self.__module__  # gets module.filename
    
    def get_module():
        A.__module__ # also gets module.filename
    

    【讨论】:

    • 感谢您的评论和投反对票。我没有阅读您的编辑,所以我想这是公平的..
    猜你喜欢
    • 1970-01-01
    • 2020-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-30
    • 1970-01-01
    • 1970-01-01
    • 2021-11-26
    相关资源
    最近更新 更多