问题描述
我需要知道一个 python 模块是否存在,而不需要导入它.
I need to know if a python module exists, without importing it.
导入可能不存在的东西(不是我想要的):
Importing something that might not exist (not what I want):
try:
import eggs
except ImportError:
pass
推荐答案
Python2
使用imp
import imp
try:
imp.find_module('eggs')
found = True
except ImportError:
found = False
要找到虚线导入,您需要做更多的事情:
To find dotted imports, you need to do more:
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部分大致相同
You can also use pkgutil.find_loader
(more or less the same as the python3 part
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
我的期望是,如果你能为它找到一个加载器,那么它就存在.你也可以更聪明一点,比如过滤掉你会接受的加载器.例如:
My expectation being, if you can find a loader for it, then it exists. You can also be a bit more smart about it, like filtering out what loaders you will accept. For example:
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
,如果你想加载一个特定的文件,这很有用.弄清楚如何使用它们超出了本文的范围.
Python3 ≥ 3.4
In Python3.4 importlib.find_loader
python docs was deprecated in favour of importlib.util.find_spec
. The recommended method is the importlib.util.find_spec
. There are others like importlib.machinery.FileFinder
, which is useful if you're after a specific file to load. Figuring out how to use them is beyond the scope of this.
import importlib
spam_spec = importlib.util.find_spec("spam")
found = spam_spec is not None
这也适用于相对导入,但您必须提供起始包,所以你也可以这样做:
This also works with relative imports but you must supply the startingpackage, so you could also do:
import importlib
spam_spec = importlib.util.find_spec("..spam", package="eggs.bar")
found = spam_spec is not None
spam_spec.name == "eggs.spam"
虽然我确信这样做是有原因的 - 我不确定它会是什么.
While I'm sure there exists a reason for doing this - I'm not sure what it would be.
当试图找到一个子模块时,它会导入父模块(对于所有上述方法)!
When trying to find a submodule, it will import the parent module (for all of the above methods)!
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')
欢迎评论解决这个问题
- @rvighne 用于 importlib
- @lucas-guido for python3.3+ 贬低
find_loader
- @enpenax 用于 python2.7 中的 pkgutils.find_loader 行为
这篇关于如何在不导入的情况下检查python模块是否存在的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!