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

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


当前回答

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

import importlib.util

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

示例输出:

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

其他回答

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'

如果你导入的是一个site-package(例如pandas),我建议这样获取它的目录(如果import是一个模块,例如pathlib):

from importlib import resources  # part of core Python
import pandas as pd

package_dir = resources.path(package=pd, resource="").__enter__()

在一般情况下。当任务是关于访问站点包的路径/资源时,可以考虑资源。

正如其他答案所说,最好的方法是使用__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 

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

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

import importlib.util

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

示例输出:

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

当你导入一个模块时,你可以访问大量的信息。检查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'>