如何检索模块的路径?
我想检测模块是否已更改。 现在,使用 inotify 很简单,您只需要知道要从中获取通知的目录即可。
如何在 python 中检索模块的路径?
I want to detect whether module has changed. Now, using inotify is simple, you just need to know the directory you want to get notifications from.
How do I retrieve a module's path in python?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(26)
实际上会给你加载的 .pyc 文件的路径,至少在 Mac OS X 上。所以我想你可以这样做:
你也可以尝试:
获取模块的目录。
Will actually give you the path to the .pyc file that was loaded, at least on Mac OS X. So I guess you can do:
You can also try:
To get the module's directory.
python中有
inspect
模块。官方文档
例子:
There is
inspect
module in python.Official documentation
Example:
正如其他答案所说,最好的方法是使用
__file__
(下面再次演示)。 但是,有一个重要的警告,即如果您单独运行该模块(即作为__main__
),则__file__
不存在。例如,假设您有两个文件(两者都在您的 PYTHONPATH 上):
运行
foo.py 将给出输出:
但是,如果您尝试单独运行 bar.py,您将得到:
希望这会有所帮助。 在测试所提供的其他解决方案时,这个警告花费了我大量的时间和困惑。
As the other answers have said, the best way to do this is with
__file__
(demonstrated again below). However, there is an important caveat, which is that__file__
does NOT exist if you are running the module on its own (i.e. as__main__
).For example, say you have two files (both of which are on your PYTHONPATH):
and
Running foo.py will give the output:
HOWEVER if you try to run bar.py on its own, you will get:
Hope this helps. This caveat cost me a lot of time and confusion while testing the other solutions presented.
我也会尝试解决这个问题的一些变化:
(其中一些问题已在SO上提出,但已关闭 对于
使用
__file__
的注意事项已导入的模块:
将返回模块的绝对路径。 但是,给定以下脚本 foo.py:
使用“python foo.py”调用它将简单地返回“foo.py”。 如果添加 shebang:
并使用 ./foo.py 调用它,它将返回“./foo.py”。 从不同的目录调用它(例如将 foo.py 放在目录 bar 中),然后调用
或添加 shebang 并直接执行该文件:
将返回“bar/foo.py”(相对小路)。
查找目录
现在从那里获取目录,
os.path.dirname(__file__)
也可能很棘手。 至少在我的系统上,如果您从与文件相同的目录调用它,它会返回一个空字符串。 前任。将输出:
换句话说,它返回一个空字符串,因此如果您想将它用于当前的文件(而不是文件),这似乎不可靠导入的模块)。 为了解决这个问题,您可以将其包装在对 abspath: 的调用中,
该调用输出类似以下内容:
请注意,abspath() 不会解析符号链接。 如果您想这样做,请改用 realpath()。 例如,创建一个指向 file_import_testing.py 的符号链接 file_import_testing_link,内容如下:
执行将打印绝对路径,如下所示:
file_import_testing_link -> file_import_testing.py
使用检查
@SummerBreeze 提到使用 inspect 模块。
对于导入的模块来说,这似乎工作得很好,而且非常简洁:
乖乖地返回绝对路径。 为了查找当前正在执行的脚本的路径:(
感谢@jbochi)
给出了当前正在执行的脚本的绝对路径(感谢@Sadman_Sakib)。
I will try tackling a few variations on this question as well:
(Some of these questions have been asked on SO, but have been closed as duplicates and redirected here.)
Caveats of Using
__file__
For a module that you have imported:
will return the absolute path of the module. However, given the folowing script foo.py:
Calling it with 'python foo.py' Will return simply 'foo.py'. If you add a shebang:
and call it using ./foo.py, it will return './foo.py'. Calling it from a different directory, (eg put foo.py in directory bar), then calling either
or adding a shebang and executing the file directly:
will return 'bar/foo.py' (the relative path).
Finding the directory
Now going from there to get the directory,
os.path.dirname(__file__)
can also be tricky. At least on my system, it returns an empty string if you call it from the same directory as the file. ex.will output:
In other words, it returns an empty string, so this does not seem reliable if you want to use it for the current file (as opposed to the file of an imported module). To get around this, you can wrap it in a call to abspath:
which outputs something like:
Note that abspath() does NOT resolve symlinks. If you want to do this, use realpath() instead. For example, making a symlink file_import_testing_link pointing to file_import_testing.py, with the following content:
executing will print absolute paths something like:
file_import_testing_link -> file_import_testing.py
Using inspect
@SummerBreeze mentions using the inspect module.
This seems to work well, and is quite concise, for imported modules:
obediently returns the absolute path. For finding the path of the currently executing script:
(thanks @jbochi)
gives the absolute path of currently executing script (thanks @Sadman_Sakib).
我不明白为什么没有人谈论这个,但对我来说,最简单的解决方案是使用 imp.find_module("modulename") (文档 此处):
它给出了一个元组,其路径位于第二位置:
此方法相对于“检查”方法的优点是您不需要导入模块即可使其工作,并且可以在输入中使用字符串。 例如,在检查另一个脚本中调用的模块时很有用。
编辑:
在python3中,
importlib
模块应该这样做:importlib.util.find_spec
的文档:I don't get why no one is talking about this, but to me the simplest solution is using imp.find_module("modulename") (documentation here):
It gives a tuple with the path in second position:
The advantage of this method over the "inspect" one is that you don't need to import the module to make it work, and you can use a string in input. Useful when checking modules called in another script for example.
EDIT:
In python3,
importlib
module should do:Doc of
importlib.util.find_spec
:这是微不足道的。
每个模块都有一个
__file__
变量,显示其与您现在所在位置的相对路径。因此,获取模块的目录以通知它很简单:
This was trivial.
Each module has a
__file__
variable that shows its relative path from where you are right now.Therefore, getting a directory for the module to notify it is simple as:
来源
Source
如果您想检索模块路径而不加载:
示例输出:
If you want to retrieve the module path without loading it:
Example output:
命令行实用程序
您可以将其调整为命令行实用程序,
创建
/usr/local/bin/python-which
使其可执行
Command Line Utility
You can tweak it to a command line utility,
Create
/usr/local/bin/python-which
Make it executable
你可以只导入你的模块
然后点击它的名字,你就会得到它的完整路径
you can just import your module
then hit its name and you'll get its full path
当您导入模块时,您可以访问大量信息。 查看
dir(a_module)
。 至于路径,有一个dunder:a_module.__path__
。 您也可以只打印模块本身。When you import a module, yo have access to plenty of information. Check out
dir(a_module)
. As for the path, there is a dunder for that:a_module.__path__
. You can also just print the module itself.呃……
Er...
所以我花了相当多的时间尝试用 py2exe 来做到这一点
问题是获取脚本的基本文件夹,无论它是作为 python 脚本还是作为 py2exe 可执行文件运行。 还要让它工作,无论它是从当前文件夹、另一个文件夹还是从系统路径运行(这是最难的)。
最终我使用了这种方法,使用 sys.frozen 作为 py2exe 中运行的指示器:
So I spent a fair amount of time trying to do this with py2exe
The problem was to get the base folder of the script whether it was being run as a python script or as a py2exe executable. Also to have it work whether it was being run from the current folder, another folder or (this was the hardest) from the system's path.
Eventually I used this approach, using sys.frozen as an indicator of running in py2exe:
如果您想从包的任何模块中检索包的根路径,可以使用以下方法(在 Python 3.6 上测试):
主
__init__.py
路径也可以通过使用__file__
来引用代码> 代替。希望这可以帮助!
If you want to retrieve the package's root path from any of its modules, the following works (tested on Python 3.6):
The main
__init__.py
path can also be referenced by using__file__
instead.Hope this helps!
如果您使用 pip 安装它,“pip show”效果很好(“位置”)
$ pip show detectorron2
更新:
$ python -m pip show mymodule
(作者:wisbucky)
If you installed it using pip, "pip show" works great ('Location')
$ pip show detectron2
Update:
$ python -m pip show mymodule
(author: wisbucky)
如果您想知道脚本中的绝对路径,可以使用 Path 对象:
cwd() 方法
resolve() 方法
If you would like to know absolute path from your script you can use Path object:
cwd() method
resolve() method
如果使用 __file__ 的唯一警告是当当前相对目录为空时(即,当从脚本所在的同一目录作为脚本运行时),那么一个简单的解决方案是:
结果:
诀窍在于
dirname()
调用之后的或 '.'
。 它将 dir 设置为.
,这意味着当前目录,并且是任何与路径相关的函数的有效目录。因此,并不真正需要使用abspath()。 但如果您无论如何使用它,则不需要这个技巧:
abspath()
接受空白路径并将其正确解释为当前目录。If the only caveat of using
__file__
is when current, relative directory is blank (ie, when running as a script from the same directory where the script is), then a trivial solution is:And the result:
The trick is in
or '.'
after thedirname()
call. It sets the dir as.
, which means current directory and is a valid directory for any path-related function.Thus, using
abspath()
is not truly needed. But if you use it anyway, the trick is not needed:abspath()
accepts blank paths and properly interprets it as the current directory.我想贡献一个常见的场景(在 Python 3 中)并探索一些实现它的方法。
内置函数 open() 接受相对或绝对路径作为它的第一个参数。 不过,相对路径被视为相对于当前工作目录,因此建议将绝对路径传递给文件。
简单地说,如果您运行包含以下代码的脚本文件,则不保证会在脚本文件所在的同一目录中创建
example.txt
文件located:要修复此代码,我们需要获取脚本的路径并将其设置为绝对路径。 为了确保路径是绝对的,我们只需使用 os .path.realpath() 函数。 要获取脚本的路径,有几个返回各种路径结果的常用函数:
os.getcwd()
os.path.realpath('example.txt')
__file__
两个函数 os.getcwd() 和 os.path.realpath() 根据当前工作目录返回路径结果。 一般不是我们想要的。 sys.argv 列表的第一个元素是 < em>根脚本的路径(您运行的脚本),无论您是在根脚本本身还是在其任何模块中调用该列表。 在某些情况下它可能会派上用场。 __file__ 变量包含调用它的模块的路径。
以下代码在脚本所在的同一目录中正确创建文件
example.txt
:I'd like to contribute with one common scenario (in Python 3) and explore a few approaches to it.
The built-in function open() accepts either relative or absolute path as its first argument. The relative path is treated as relative to the current working directory though so it is recommended to pass the absolute path to the file.
Simply said, if you run a script file with the following code, it is not guaranteed that the
example.txt
file will be created in the same directory where the script file is located:To fix this code we need to get the path to the script and make it absolute. To ensure the path to be absolute we simply use the os.path.realpath() function. To get the path to the script there are several common functions that return various path results:
os.getcwd()
os.path.realpath('example.txt')
sys.argv[0]
__file__
Both functions os.getcwd() and os.path.realpath() return path results based on the current working directory. Generally not what we want. The first element of the sys.argv list is the path of the root script (the script you run) regardless of whether you call the list in the root script itself or in any of its modules. It might come handy in some situations. The __file__ variable contains path of the module from which it has been called.
The following code correctly creates a file
example.txt
in the same directory where the script is located:这个问题的现代(Python >= 3.7)解决方案是 importlib.resources.files()
A modern (Python >= 3.7) solution to this problem is
importlib.resources.files()
在 python 包的模块中,我必须引用与 package.json 位于同一目录中的文件。 前任。
因此,在上面我必须从 my_lib_a.py 模块调用 maincli.py ,因为知道 top_package 和 maincli.py 位于同一目录中。 以下是我获取 maincli.py 路径的方法:
根据 PlasmaBinturong 的发布,我修改了代码。
From within modules of a python package I had to refer to a file that resided in the same directory as package. Ex.
So in above I had to call maincli.py from my_lib_a.py module knowing that top_package and maincli.py are in the same directory. Here's how I get the path to maincli.py:
Based on posting by PlasmaBinturong I modified the code.
如果您希望在“程序”中动态执行此操作,请尝试以下代码:
我的观点是,您可能不知道要对其进行“硬编码”的模块的确切名称。
它可以从列表中选择,也可以当前未运行以使用 __file__。
(我知道,它在 Python 3 中不起作用)
我试图摆脱“全局”问题,但发现它不起作用的情况
我认为“execfile()”可以在Python 3中模拟
由于这是在程序中,因此可以轻松地将其放入方法或模块中以供重用。
If you wish to do this dynamically in a "program" try this code:
My point is, you may not know the exact name of the module to "hardcode" it.
It may be selected from a list or may not be currently running to use __file__.
(I know, it will not work in Python 3)
I tried to get rid of the "global" issue but found cases where it did not work
I think "execfile()" can be emulated in Python 3
Since this is in a program, it can easily be put in a method or module for reuse.
这是一个快速的 bash 脚本,以防它对任何人有用。 我只是希望能够设置一个环境变量,以便我可以
pushd
到代码。外壳示例:
Here is a quick bash script in case it's useful to anyone. I just want to be able to set an environment variable so that I can
pushd
to the code.Shell example:
如果您使用
pip
,则可以调用pip show
,但必须使用您正在使用的特定版本的python
来调用它。 例如,这些都可能给出不同的结果:不要简单地运行
$ pip show numpy
,因为不能保证不同的pip
是相同的。 >python 版本正在调用。If you used
pip
, then you can callpip show
, but you must call it using the specific version ofpython
that you are using. For example, these could all give different results:Don't simply run
$ pip show numpy
, because there is no guarantee that it will be the samepip
that differentpython
versions are calling.如果您的导入是一个站点包(例如
pandas
),我建议使用此方法来获取其目录(如果导入是一个模块,则不起作用,例如pathlib
):一般情况当任务是关于访问站点包的路径/资源。
If your import is a site-package (e.g.
pandas
) I recommend this to get its directory (does not work if import is a module, like e.g.pathlib
):In general importlib.resources can be considered when a task is about accessing paths/resources of a site package.
这里我正在打印cProfile包路径:-
Here im printing cProfile package path:-