我如何知道Python模块是否存在,而不导入它?
导入一些可能不存在(不是我想要的)的东西会导致:
try:
import eggs
except ImportError:
pass
我如何知道Python模块是否存在,而不导入它?
导入一些可能不存在(不是我想要的)的东西会导致:
try:
import eggs
except ImportError:
pass
当前回答
在django.utils.module_loading.module_has_submodule:
import sys
import os
import imp
def module_has_submodule(package, module_name):
"""
check module in package
django.utils.module_loading.module_has_submodule
"""
name = ".".join([package.__name__, module_name])
try:
# None indicates a cached miss; see mark_miss() in Python/import.c.
return sys.modules[name] is not None
except KeyError:
pass
try:
package_path = package.__path__ # No __path__, then not a package.
except AttributeError:
# Since the remainder of this function assumes that we're dealing with
# a package (module with a __path__), so if it's not, then bail here.
return False
for finder in sys.meta_path:
if finder.find_module(name, package_path):
return True
for entry in package_path:
try:
# Try the cached finder.
finder = sys.path_importer_cache[entry]
if finder is None:
# Implicit import machinery should be used.
try:
file_, _, _ = imp.find_module(module_name, [entry])
if file_:
file_.close()
return True
except ImportError:
continue
# Else see if the finder knows of a loader.
elif finder.find_module(name):
return True
else:
continue
except KeyError:
# No cached finder, so try and make one.
for hook in sys.path_hooks:
try:
finder = hook(entry)
# XXX Could cache in sys.path_importer_cache
if finder.find_module(name):
return True
else:
# Once a finder is found, stop the search.
break
except ImportError:
# Continue the search for a finder.
continue
else:
# No finder found.
# Try the implicit import machinery if searching a directory.
if os.path.isdir(entry):
try:
file_, _, _ = imp.find_module(module_name, [entry])
if file_:
file_.close()
return True
except ImportError:
pass
# XXX Could insert None or NullImporter
else:
# Exhausted the search, so the module cannot be found.
return False
其他回答
下面是一种检查模块是否从命令行加载的方法:
Linux/UNIX脚本文件方法:制作文件module_help.py:
#!/usr/bin/env python
help('modules')
然后确保它是可执行的:chmod u+x module_help.py
并使用管道调用grep:
./module_help.py | grep module_name
调用内置帮助系统。(此函数用于交互使用。)如果没有给出参数,交互式帮助系统将在解释器控制台上启动。如果参数是字符串,则该字符串将被查询为模块、函数、类、方法、关键字或文档主题的名称,并在控制台上打印帮助页面。如果参数是任何其他类型的对象,则生成该对象的帮助页面。
交互方法:在控制台中,加载python
>>> help('module_name')
如果发现,输入q停止读取。 按Ctrl + D退出Python解释器交互会话
Windows脚本文件方法,也兼容Linux/UNIX,整体上更好:
#!/usr/bin/env python
import sys
help(sys.argv[1])
从命令调用它,像这样:
python module_help.py site
将输出:
模块网站帮助: 的名字 site -将第三方包的模块搜索路径附加到sys.path。 文件 /usr/lib/python2.7/site.py 模块文档 http://docs.python.org/library/site 描述 ... :
你必须按q键才能退出交互模式。
将它用于未知模块,例如,
python module_help.py lkajshdflkahsodf
将输出:
没有找到'lkajshdflkahsodf'的Python文档
并退出。
Python 3 >= 3.6: ModuleNotFoundError
ModuleNotFoundError已在Python 3.6中引入,可用于以下目的:
try:
import eggs
except ModuleNotFoundError:
# Error handling
pass
当无法找到模块或其父模块之一时,将引发此错误。所以
try:
import eggs.sub
except ModuleNotFoundError as err:
# Error handling
print(err)
如果找不到eggs模块,将打印类似于No module named 'eggs'的消息;但它会打印类似于没有名为“eggs”的模块。如果子模块找不到,但鸡蛋包可以找到,则Sub '。
有关ModuleNotFoundError的更多信息,请参阅导入系统的文档。
Go_as的回答是一行:
python -c "help('modules');" | grep module
你也可以使用importlib。util直接
import importlib.util
def module_exists_without_import(module_name):
spec = importlib.util.find_spec(module_name)
return spec is not None
没有任何方法可以在不导入其父包的情况下可靠地检查“虚线模块”是否可导入。说到这里,对于“如何检查Python模块是否存在”这个问题,有很多解决方案。
下面的解决方案解决了导入的模块即使存在也会引发ImportError的问题。我们希望将这种情况与模块不存在的情况区分开来。
Python 2:
import importlib
import pkgutil
import sys
def find_module(full_module_name):
"""
Returns module object if module `full_module_name` can be imported.
Returns None if module does not exist.
Exception is raised if (existing) module raises exception during its import.
"""
module = sys.modules.get(full_module_name)
if module is None:
module_path_tail = full_module_name.split('.')
module_path_head = []
loader = True
while module_path_tail and loader:
module_path_head.append(module_path_tail.pop(0))
module_name = ".".join(module_path_head)
loader = bool(pkgutil.find_loader(module_name))
if not loader:
# Double check if module realy does not exist
# (case: full_module_name == 'paste.deploy')
try:
importlib.import_module(module_name)
except ImportError:
pass
else:
loader = True
if loader:
module = importlib.import_module(full_module_name)
return module
Python 3:
import importlib
def find_module(full_module_name):
"""
Returns module object if module `full_module_name` can be imported.
Returns None if module does not exist.
Exception is raised if (existing) module raises exception during its import.
"""
try:
return importlib.import_module(full_module_name)
except ImportError as exc:
if not (full_module_name + '.').startswith(exc.name + '.'):
raise