本文介绍了如何在不导入的情况下检查python模块是否存在的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要知道一个 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模块是否存在的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-26 04:59