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