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

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


当前回答

当你导入一个模块时,你可以访问大量的信息。检查dir(a_module)。至于路径,有一个dunder: a_module.__path__。也可以只打印模块本身。

>>> import a_module
>>> print(dir(a_module))
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__']
>>> print(a_module.__path__)
['/.../.../a_module']
>>> print(a_module)
<module 'a_module' from '/.../.../a_module/__init__.py'>

其他回答

正如其他答案所说,最好的方法是使用__file__(下面再次演示)。然而,有一个重要的警告,即如果你单独运行模块(即作为__main__), __file__是不存在的。

例如,假设你有两个文件(都在你的PYTHONPATH上):

#/path1/foo.py
import bar
print(bar.__file__)

and

#/path2/bar.py
import os
print(os.getcwd())
print(__file__)

运行foo.py会得到如下输出:

/path1        # "import bar" causes the line "print(os.getcwd())" to run
/path2/bar.py # then "print(__file__)" runs
/path2/bar.py # then the import statement finishes and "print(bar.__file__)" runs

然而,如果你试图单独运行bar.py,你会得到:

/path2                              # "print(os.getcwd())" still works fine
Traceback (most recent call last):  # but __file__ doesn't exist if bar.py is running as main
  File "/path2/bar.py", line 3, in <module>
    print(__file__)
NameError: name '__file__' is not defined 

希望这能有所帮助。在测试其他解决方案时,这个警告花费了我大量的时间和混乱。

命令行实用程序

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

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

因此,我花了相当多的时间尝试用py2exe来实现这一点 问题是获取脚本的基本文件夹,无论它是作为python脚本还是作为py2exe可执行文件运行。此外,无论它是从当前文件夹、另一个文件夹还是(这是最难的)系统路径运行,它都能正常工作。

最终我使用了这种方法,使用sys.frozen作为py2exe中运行的指示符:

import os,sys
if hasattr(sys,'frozen'): # only when running in py2exe this exists
    base = sys.prefix
else: # otherwise this is a regular python script
    base = os.path.dirname(os.path.realpath(__file__))
import os
path = os.path.abspath(__file__)
dir_path = os.path.dirname(path)
import module
print module.__path__

包还支持一个特殊的属性__path__。这是 初始化为包含保存目录名称的列表 在执行该文件中的代码之前,包的__init__.py。 这个变量可以修改;这样做会影响将来的搜索 包中包含的模块和子包。 虽然不经常需要此特性,但可以使用它来扩展 在包中找到的模块集。