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

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


当前回答

如果使用__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()接受空白路径并将其正确地解释为当前目录。

其他回答

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'

命令行实用程序

您可以将其调整为命令行实用程序,

python-which <package name>


创建/usr/local/bin/python-which

#!/usr/bin/env python

import importlib
import os
import sys

args = sys.argv[1:]
if len(args) > 0:
    module = importlib.import_module(args[0])
    print os.path.dirname(module.__file__)

使其可执行

sudo chmod +x /usr/local/bin/python-which

下面是一个快速bash脚本,以防它对任何人都有用。我只是想设置一个环境变量,这样我就能把它推到代码中。

#!/bin/bash
module=${1:?"I need a module name"}

python << EOI
import $module
import os
print os.path.dirname($module.__file__)
EOI

壳牌的例子:

[root@sri-4625-0004 ~]# export LXML=$(get_python_path.sh lxml)
[root@sri-4625-0004 ~]# echo $LXML
/usr/lib64/python2.7/site-packages/lxml
[root@sri-4625-0004 ~]#

我不明白为什么没有人谈论这个,但对我来说,最简单的解决方案是使用imp.find_module("modulename")(文档在这里):

import imp
imp.find_module("os")

它给出了一个位于第二位置的元组:

(<open file '/usr/lib/python2.7/os.py', mode 'U' at 0x7f44528d7540>,
'/usr/lib/python2.7/os.py',
('.py', 'U', 1))

与“inspect”方法相比,此方法的优点是您不需要导入模块来使其工作,并且可以在输入中使用字符串。例如,在检查另一个脚本中调用的模块时非常有用。

编辑:

在python3中,importlib模块应该这样做:

importlib.util.find_spec的文档:

Return the spec for the specified module. First, sys.modules is checked to see if the module was already imported. If so, then sys.modules[name].spec is returned. If that happens to be set to None, then ValueError is raised. If the module is not in sys.modules, then sys.meta_path is searched for a suitable spec with the value of 'path' given to the finders. None is returned if no spec could be found. If the name is for submodule (contains a dot), the parent module is automatically imported. The name and package arguments work the same as importlib.import_module(). In other words, relative module names (with leading dots) work.

如果使用pip,则可以调用pip show,但必须使用正在使用的特定python版本调用它。例如,这些都可能给出不同的结果:

$ python -m pip show numpy
$ python2.7 -m pip show numpy
$ python3 -m pip show numpy

Location: /System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python

不要简单地运行$ pip show numpy,因为不能保证不同的python版本调用的是同一个pip。