Python2
使用imp检查导入是否可以在python2中找到东西
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(和python3部分差不多
import pkgutil
eggs_loader = pkgutil.find_loader('eggs')
found = eggs_loader is not None
Python3
Python3 ≤ 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)
Python3≥3.4
在 Python3.4 中,importlib.find_loader python docs 被弃用,取而代之的是 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.find_spec("food.eggs")
module food loaded
ModuleSpec(name='food.eggs', loader=<_frozen_importlib.SourceFileLoader object at 0x10221df28>, origin='/home/user/food/eggs.py')
欢迎 cmets 解决这个问题
致谢
- @rvighne 用于 importlib
- @lucas-guido for python3.3+ 贬低
find_loader
- @enpenax 用于 python2.7 中的 pkgutils.find_loader 行为