我想检测模块是否发生了变化。现在,使用inotify很简单,你只需要知道你想从哪个目录获取通知。

如何在python中检索模块的路径?


当前回答

python中有inspect模块。

官方文档

inspect模块提供了几个有用的函数来帮助获取 有关活动对象的信息,如模块、类、方法、 函数、回溯、帧对象和代码对象。例如, 它可以帮助您检查类的内容,检索源 方法的代码,提取并格式化函数的参数列表, 或者获取显示详细回溯所需的所有信息。

例子:

>>> import os
>>> import inspect
>>> inspect.getfile(os)
'/usr/lib64/python2.7/os.pyc'
>>> inspect.getfile(inspect)
'/usr/lib64/python2.7/inspect.pyc'
>>> os.path.dirname(inspect.getfile(inspect))
'/usr/lib64/python2.7'

其他回答

import a_module
print(a_module.__file__)

会给你已经加载的。pyc文件的路径,至少在Mac OS x上是这样的

import os
path = os.path.abspath(a_module.__file__)

你也可以试试:

path = os.path.dirname(a_module.__file__)

获取模块的目录。

我也会尝试解决这个问题的一些变化:

查找被调用脚本的路径 查找当前执行脚本的路径 查找被调用脚本的目录

(其中一些问题已经在SO上被问过,但在这里已经被关闭并重新定向。)

使用__file__的注意事项

对于已导入的模块:

import something
something.__file__ 

将返回模块的绝对路径。然而,给定下面的脚本foo.py:

#foo.py
print '__file__', __file__

用'python foo.py'调用它只会返回'foo.py'。如果你加上一个shebang:

#!/usr/bin/python 
#foo.py
print '__file__', __file__

并使用。/foo.py调用它,它将返回'./foo.py'。从不同的目录调用它(例如把foo.py放在目录栏中),然后调用任何一个

python bar/foo.py

或者添加一个shebang并直接执行文件:

bar/foo.py

将返回'bar/foo.py'(相对路径)。

查找目录

现在从那里获取目录os.path.dirname(__file__)也可能很棘手。至少在我的系统上,如果从与文件相同的目录调用它,它将返回一个空字符串。前女友。

# foo.py
import os
print '__file__ is:', __file__
print 'os.path.dirname(__file__) is:', os.path.dirname(__file__)

将输出:

__file__ is: foo.py
os.path.dirname(__file__) is: 

换句话说,它返回一个空字符串,所以如果您想将它用于当前文件(而不是导入模块的文件),这似乎不可靠。为了解决这个问题,你可以调用abspath:

# foo.py
import os
print 'os.path.abspath(__file__) is:', os.path.abspath(__file__)
print 'os.path.dirname(os.path.abspath(__file__)) is:', os.path.dirname(os.path.abspath(__file__))

输出如下:

os.path.abspath(__file__) is: /home/user/bar/foo.py
os.path.dirname(os.path.abspath(__file__)) is: /home/user/bar

注意,abspath()不解析符号链接。如果您想这样做,请使用realpath()。例如,创建一个符号链接file_import_testing_link指向file_import_testing.py,内容如下:

import os
print 'abspath(__file__)',os.path.abspath(__file__)
print 'realpath(__file__)',os.path.realpath(__file__)

执行将输出绝对路径,如下所示:

abspath(__file__) /home/user/file_test_link
realpath(__file__) /home/user/file_test.py

File_import_testing_link -> file_import_testing.py

使用检查

@SummerBreeze提到了使用inspect模块。

对于导入的模块,这似乎工作得很好,而且相当简洁:

import os
import inspect
print 'inspect.getfile(os) is:', inspect.getfile(os)

返回绝对路径。查找当前执行脚本的路径:

inspect.getfile(inspect.currentframe())

(感谢@jbochi)

inspect.getabsfile(inspect.currentframe()) 

给出了当前执行脚本的绝对路径(感谢@Sadman_Sakib)。

如果你想在不加载的情况下检索模块路径:

import importlib.util

print(importlib.util.find_spec("requests").origin)

示例输出:

/usr/lib64/python3.9/site-packages/requests/__init__.py

如果使用__file__的唯一注意事项是当前相对目录为空(即,当脚本从脚本所在的同一目录运行时,作为脚本运行),那么一个简单的解决方案是:

import os.path
mydir = os.path.dirname(__file__) or '.'
full  = os.path.abspath(mydir)
print __file__, mydir, full

结果是:

$ python teste.py 
teste.py . /home/user/work/teste

诀窍在于“或”。'在dirname()调用之后。它将dir设置为.,这意味着当前目录,并且对于任何与路径相关的函数都是有效的目录。

因此,实际上并不需要使用abspath()。但是如果您无论如何都使用它,那么就不需要这个技巧了:abspath()接受空白路径并将其正确地解释为当前目录。

如果你使用pip安装它,“pip show”工作得很好(“Location”)

$ PIP show detectron2

Name: detectron2
Version: 0.1
Summary: Detectron2 is FAIR next-generation research platform for object detection and segmentation.
Home-page: https://github.com/facebookresearch/detectron2
Author: FAIR
Author-email: None
License: UNKNOWN
Location: /home/ubuntu/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages
Requires: yacs, tabulate, tqdm, pydot, tensorboard, Pillow, termcolor, future, cloudpickle, matplotlib, fvcore

更新:

$ python -m PIP show mymodule

(author: wisbucky。)