我想检测模块是否已更改.现在,使用inotify很简单,您只需要知道要从中获取通知的目录.
如何在python中检索模块的路径?
import a_module print(a_module.__file__)
实际上会给你加载的.pyc文件的路径,至少在Mac OS X上.所以我想你可以这样做:
import os path = os.path.abspath(a_module.__file__)
你也可以尝试:
path = os.path.dirname(a_module.__file__)
获取模块的目录.
inspect
python中有模块.
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'
正如其他答案所说,做到这一点的最好方法是__file__
(再次在下面说明).但是,有一个重要的警告,即__file__
如果您自己运行模块(即as __main__
),则不存在.
例如,假设您有两个文件(两个文件都在您的PYTHONPATH上):
#/path1/foo.py import bar print(bar.__file__)
和
#/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, inprint(__file__) NameError: name '__file__' is not defined
希望这可以帮助.在测试所提出的其他解决方案时,这个警告花费了我很多时间和困惑.
我会尝试解决这个问题的一些变化:
找到被调用脚本的路径
找到当前正在执行的脚本的路径
找到被调用脚本的目录
(其中一些问题已在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.py的符号链接file_import_testing_link:
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)
顺从地返回绝对路径.但是,为了找到当前正在执行的脚本的路径,我没有看到使用它的方法.
我不明白为什么没有人在谈论这个,但对我来说最简单的解决方案是使用imp.find_module("modulename")(这里的文档):
import imp imp.find_module("os")
它给出了一个元组,其路径位于第二位:
(, '/usr/lib/python2.7/os.py', ('.py', 'U', 1))
这种方法优于"检查"方法的优点是您不需要导入模块使其工作,您可以在输入中使用字符串.例如,检查在另一个脚本中调用的模块时很有用.
编辑:
在python3中,importlib
模块应该:
文件importlib.util.find_spec
:
返回指定模块的规范.
首先,检查sys.modules以查看模块是否已导入.如果是,则sys.modules [name].spec返回.如果碰巧将其设置为None,则会引发ValueError.如果模块不在sys.modules中,则会在sys.meta_path中搜索合适的规范,并为查找程序提供值"path".如果找不到规范,则返回None.
如果名称用于子模块(包含点),则会自动导入父模块.
name和package参数与importlib.import_module()的作用相同.换句话说,相对模块名称(带有前导点)起作用.
这是微不足道的.
每个模块都有一个__file__
变量,显示您现在所处的相对路径.
因此,获取模块的目录以通知它很简单:
os.path.dirname(__file__)
import os path = os.path.abspath(__file__) dir_path = os.path.dirname(path)
您可以将其调整为命令行实用程序,
python-which
创建 /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
import module print module.__path__
包支持另一个特殊属性
__path__
.这被初始化为一个列表,其中包含在__init__.py
执行该文件中的代码之前保存包的目录的名称.这个变量可以修改; 这样做会影响将来对包中包含的模块和子包的搜索.虽然通常不需要此功能,但它可用于扩展程序包中的模块集.
资源
所以我花了相当多的时间尝试用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 >>> os>>>