我想检测模块是否发生了变化。现在,使用inotify很简单,你只需要知道你想从哪个目录获取通知。
如何在python中检索模块的路径?
我想检测模块是否发生了变化。现在,使用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'
其他回答
因此,我花了相当多的时间尝试用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__))
如果使用__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'
我也会尝试解决这个问题的一些变化:
查找被调用脚本的路径 查找当前执行脚本的路径 查找被调用脚本的目录
(其中一些问题已经在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)。
我想提供一个常见的场景(在Python 3中),并探索一些实现它的方法。
内置函数open()接受相对路径或绝对路径作为其第一个参数。相对路径被视为相对于当前工作目录,因此建议将绝对路径传递给文件。
简单地说,如果你用下面的代码运行一个脚本文件,并不保证example.txt文件会被创建在脚本文件所在的同一目录下:
with open('example.txt', 'w'):
pass
要修复这段代码,我们需要获取脚本的路径,并使其成为绝对路径。为了确保路径是绝对的,我们只需使用os.path.realpath()函数。为了获得脚本的路径,有几个常见的函数返回不同的路径结果:
os.getcwd() os.path.realpath('example.txt') sys.argv[0] __文件__
os.getcwd()和os.path.realpath()函数都会返回基于当前工作目录的路径结果。通常不是我们想要的。系统的第一个元素。Argv list是根脚本(您运行的脚本)的路径,而不管您是在根脚本本身中还是在其任何模块中调用该列表。在某些情况下可能会派上用场。__file__变量包含调用它的模块的路径。
下面的代码正确地在脚本所在的目录中创建了一个文件example.txt:
filedir = os.path.dirname(os.path.realpath(__file__))
filepath = os.path.join(filedir, 'example.txt')
with open(filepath, 'w'):
pass