python - 如何在不导入的情况下检查 Python 模块是否存在

如果不导入 Python 模块,我如何知道它是否存在?

导入可能不存在的东西(不是我想要的)会导致:

try:
    import eggs
except ImportError:
    pass

最佳答案

Python2

使用 imp 检查 import 是否可以在 Python 2 中找到某些内容:

import imp
try:
    imp.find_module('eggs')
    found = True
except ImportError:
    found = False

要查找点式导入,您需要做更多工作:

import imp
try:
    spam_info = imp.find_module('spam')
    spam = imp.load_module('spam', *spam_info)
    imp.find_module('eggs', spam.__path__) # __path__ is already a list
    found = True
except ImportError:
    found = False

您也可以使用 pkgutil.find_loader(与 Python 3 部分大致相同:

import pkgutil
eggs_loader = pkgutil.find_loader('eggs')
found = eggs_loader is not None

Python 3

Python 3 ≤ 3.3

您应该使用 importlib。我开始这样做:

import importlib
spam_loader = importlib.find_loader('spam')
found = spam_loader is not None

我的期望是,如果你能找到它的加载器,那么它就存在。你也可以更聪明一点,比如过滤掉你会接受的加载器。例如:

import importlib
spam_loader = importlib.find_loader('spam')
# only accept it as valid if there is a source file for the module - no bytecode only.
found = issubclass(type(spam_loader), importlib.machinery.SourceFileLoader)

Python 3 ≥ 3.4

在 Python 3.4 中 importlib.find_loader Python documentation已弃用,取而代之的是 importlib.util.find_spec。推荐的方法是 importlib.util.find_spec。还有其他类似 importlib.machinery.FileFinder,如果您要加载特定文件,这很有用。弄清楚如何使用它们超出了本文的范围。

import importlib
spam_spec = importlib.util.find_spec("spam")
found = spam_spec is not None

这也适用于相对导入,但您必须提供起始包,因此您也可以这样做:

import importlib
spam_spec = importlib.util.find_spec("..spam", package="eggs.bar")
found = spam_spec is not None
spam_spec.name == "eggs.spam"

虽然我确信这样做是有原因的 - 但我不确定它会是什么。

警告

当试图找到一个子模块时,它会导入父模块(对于上述方法的所有)!

food/
  |- __init__.py
  |- eggs.py

## __init__.py
print("module food loaded")

## eggs.py
print("module eggs")

were you then to run
>>> import importlib
>>> spam_spec = importlib.util.find_spec("food.eggs")
module food loaded
ModuleSpec(name='food.eggs', loader=<_frozen_importlib.SourceFileLoader object at 0x10221df28>, origin='/home/user/food/eggs.py')

欢迎评论解决这个问题

致谢

  • @rvighne 用于导入库
  • @lucas-guido for Python 3.3+ 弃用 find_loader
  • @enpenax 用于 Python 2.7 中的 pkgutils.find_loader 行为

https://stackoverflow.com/questions/14050281/

相关文章:

python - ConfigParser 中的列表

linux - 使用 bash 为文件添加文件扩展名

linux - 选择 Linux I/O 调度程序

linux - 什么包包括 AB Ubuntu 中的 Apache 服务器基准测试工具

python - 未找到 Virtualenv 命令

linux - 仅使用 shell 脚本从文本文件中获取特定行

python - 使用Python在SQLite中插入行后如何检索插入的ID?

ruby - 找不到 gem 命令

python - 仅在 Django 启动 ONCE 时执行代码?

python - 如何在python中打印百分比值?