我想检测模块是否发生了变化。现在,使用inotify很简单,你只需要知道你想从哪个目录获取通知。
如何在python中检索模块的路径?
我想检测模块是否发生了变化。现在,使用inotify很简单,你只需要知道你想从哪个目录获取通知。
如何在python中检索模块的路径?
当前回答
如果你想在一个“程序”中动态地做到这一点,试试下面的代码: 我的观点是,你可能不知道模块的确切名称来“硬编码”它。 它可以从列表中选择,也可以当前未运行以使用__file__。
(我知道,它在python3中不起作用)
global modpath
modname = 'os' #This can be any module name on the fly
#Create a file called "modname.py"
f=open("modname.py","w")
f.write("import "+modname+"\n")
f.write("modpath = "+modname+"\n")
f.close()
#Call the file with execfile()
execfile('modname.py')
print modpath
<module 'os' from 'C:\Python27\lib\os.pyc'>
我试图摆脱“全球”问题,但发现在某些情况下它不起作用 我认为"execfile()"可以在python3中模拟 由于这是在程序中,所以可以很容易地将其放入方法或模块中进行重用。
其他回答
您可以导入您的模块 然后点击它的名字,你会得到它的完整路径
>>> import os
>>> os
<module 'os' from 'C:\\Users\\Hassan Ashraf\\AppData\\Local\\Programs\\Python\\Python36-32\\lib\\os.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()接受空白路径并将其正确地解释为当前目录。
我也会尝试解决这个问题的一些变化:
查找被调用脚本的路径 查找当前执行脚本的路径 查找被调用脚本的目录
(其中一些问题已经在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)。
当你导入一个模块时,你可以访问大量的信息。检查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'>
如果你想在不加载的情况下检索模块路径:
import importlib.util
print(importlib.util.find_spec("requests").origin)
示例输出:
/usr/lib64/python3.9/site-packages/requests/__init__.py