如何获取当前运行的模块路径/名称

时间:2022-03-07 23:45:27

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.

我有一个文件a / b / c.py,可以用python -m a.b.c调用。我想在模块级别获取值a.b.c。


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.

因此,当我收到-h选项时,我显示USAGE而不需要在每个脚本中实际记下实际值。

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

编辑:如上所述,有答案(我已经搜索过),但不是简单的答案。要么使用inspect,要么使用traceback,要么操作__file__和__package__并做一些子字符串来得到答案。但没有什么比我在模块中有一个类的简单,我可以使用myClass .__ module__,我会得到我想要的答案。 (遗憾的是)使用__name__是无用的,因为它始终是__main__。

Also, this is in python 2.6 and I cannot use any other versions.

此外,这是在python 2.6中,我不能使用任何其他版本。

8 个解决方案

#1


26  

This works for me:

这对我有用:

__loader__.fullname

Also if I do python -m b.c from a\ I get 'b.c' as expected.

另外如果我从一个\来做python -m b.c我按预期得到'b.c'。

Not entirely sure what the __loader__ attribute is so let me know if this is no good.

不完全确定__loader__属性是什么,所以让我知道这是不是很好。

edit: It comes from PEP 302: http://www.python.org/dev/peps/pep-0302/

编辑:它来自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:

load_module()方法在运行任何代码之前必须履行一些职责:

...

  • 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.
  • 它应该为模块添加一个__loader__属性,设置为loader对象。这主要用于内省,但可用于特定于导入程序的附加功能,例如获取与导入程序关联的数据。

So it looks like it should work fine in all cases.

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

#2


11  

I think you're actually looking for the __name__ special variable. From the Python documentation:

我想你实际上在寻找__name__特殊变量。从Python文档:

Within a module, the module’s name (as a string) is available as the value of the global variable __name__.

在模块中,模块的名称(作为字符串)可用作全局变量__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.

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

#3


6  

When run with -m, sys.path[0] contains the full path to the module. You could use that to build the name.

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

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

Another option may be the __package__ built in variable which is available within modules.

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

#4


1  

The only way is to do path manipulation with os.getcwd(), os.path, file and whatnot, as you mentioned.

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

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.

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

#5


0  

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.

看不出为什么有“python -m a.b.c”这样的限制。当然,实际的模块可能在某些zip或其他任何内容中,但我宁愿使用包装器脚本简化整个方法,这样可以确保在正确的上下文中使用正确的python实例执行。

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.

回到原来的要求。如果我理解正确,那就是有人在某个子子目录中运行python文件,从使用消息中找出它实际上是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%.

我认为,没有可靠的,通用的方法来确定一个想运行C,BC或ABC模块,没有一定的启发一些文件系统的分析(比如,发现外目录,直到点的所有__init__.py不存在更多__init__.py),即使分析不是100%。

#6


-1  

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.

你应该在你的帮助中硬编码a.b.c,如果你这样分发包,那么不管文件系统中的位置是什么,只要在PYTHONPATH它将被导入它就可以调用它。

#7


-1  

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.

首先要熟悉Python中__file__的使用,点击这里查看用法。

It holds the name of currently loaded module.

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

Check/Try the following code, it will work on both Python2 & Python3.

检查/尝试以下代码,它将适用于Python2和Python3。

# module_names.py 

import os

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

Output on MAC OS X:

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.

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

#8


-1  

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

#1


26  

This works for me:

这对我有用:

__loader__.fullname

Also if I do python -m b.c from a\ I get 'b.c' as expected.

另外如果我从一个\来做python -m b.c我按预期得到'b.c'。

Not entirely sure what the __loader__ attribute is so let me know if this is no good.

不完全确定__loader__属性是什么,所以让我知道这是不是很好。

edit: It comes from PEP 302: http://www.python.org/dev/peps/pep-0302/

编辑:它来自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:

load_module()方法在运行任何代码之前必须履行一些职责:

...

  • 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.
  • 它应该为模块添加一个__loader__属性,设置为loader对象。这主要用于内省,但可用于特定于导入程序的附加功能,例如获取与导入程序关联的数据。

So it looks like it should work fine in all cases.

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

#2


11  

I think you're actually looking for the __name__ special variable. From the Python documentation:

我想你实际上在寻找__name__特殊变量。从Python文档:

Within a module, the module’s name (as a string) is available as the value of the global variable __name__.

在模块中,模块的名称(作为字符串)可用作全局变量__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.

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

#3


6  

When run with -m, sys.path[0] contains the full path to the module. You could use that to build the name.

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

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

Another option may be the __package__ built in variable which is available within modules.

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

#4


1  

The only way is to do path manipulation with os.getcwd(), os.path, file and whatnot, as you mentioned.

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

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.

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

#5


0  

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.

看不出为什么有“python -m a.b.c”这样的限制。当然,实际的模块可能在某些zip或其他任何内容中,但我宁愿使用包装器脚本简化整个方法,这样可以确保在正确的上下文中使用正确的python实例执行。

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.

回到原来的要求。如果我理解正确,那就是有人在某个子子目录中运行python文件,从使用消息中找出它实际上是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%.

我认为,没有可靠的,通用的方法来确定一个想运行C,BC或ABC模块,没有一定的启发一些文件系统的分析(比如,发现外目录,直到点的所有__init__.py不存在更多__init__.py),即使分析不是100%。

#6


-1  

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.

你应该在你的帮助中硬编码a.b.c,如果你这样分发包,那么不管文件系统中的位置是什么,只要在PYTHONPATH它将被导入它就可以调用它。

#7


-1  

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.

首先要熟悉Python中__file__的使用,点击这里查看用法。

It holds the name of currently loaded module.

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

Check/Try the following code, it will work on both Python2 & Python3.

检查/尝试以下代码,它将适用于Python2和Python3。

# module_names.py 

import os

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

Output on MAC OS X:

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.

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

#8


-1  

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