Python 如何检查模块是否可用于导入?

Python 如何检查模块是否可用于导入?,python,module,styles,Python,Module,Styles,我在脚本中使用一个模块,但主机应用程序中的一个操作没有加载此模块,因此脚本失败。如果因为不需要运行而失败也可以,但我不想看到错误消息框 是否有办法检查模块是否可用,例如: isavailable ( mymodule ) # safe to use the module 但我也希望函数提前返回,如果不可用,则中断执行。您可以执行以下操作: try: import my_module except ImportError: available = False else:

我在脚本中使用一个模块,但主机应用程序中的一个操作没有加载此模块,因此脚本失败。如果因为不需要运行而失败也可以,但我不想看到错误消息框

是否有办法检查模块是否可用,例如:

isavailable ( mymodule )

# safe to use the module

但我也希望函数提前返回,如果不可用,则中断执行。

您可以执行以下操作:

try:
    import my_module
except ImportError:
    available = False
else:
    available = True
import importlib

def import_if_available(name, package=None):
    try:
        return importlib.import_module(name, package)
    except ImportError:
        return None

print import_if_available('os.path')
来自文件

importlib包的用途有两个。一个是在Python源代码中提供import语句的实现(因此,通过扩展,import()函数)。这提供了一个可移植到任何Python解释器的导入实现。这还提供了一个参考实现,它比用Python以外的编程语言实现的更容易理解。
第二,实现导入的组件在此包中公开,使用户可以更轻松地创建自己的自定义对象(通常称为导入器)以参与导入过程。有关自定义导入程序的详细信息可以在PEP 302中找到。

尽管希望调用的函数停止执行有点不寻常,但您可以这样做,如下所示。您必须将模块名称作为字符串传递给函数,因为变量
mymodule
在调用时可能还不存在。如果成功,它将返回导入的模块,以便将结果分配给变量名以供后续使用

import sys

def isavailable(modulename):
    try:
        module = __import__(modulename)
    except ImportError:
        sys.exit(1)  # stop execution
    else:
        return module
示例用法:

mymodule = isavailable('mymodule')  # program will terminate if not found
mymodule.method()

检查模块是否可用的最简单方法是导入它。这几乎总是你想要的。如果模块不可用,则此操作将失败。如果模块可用…那么,您检查的原因是您需要验证是否能够导入它,这样您就不会浪费任何时间导入它了

更一般地说,在Python中,它是。如果你想知道你是否能做点什么,就试着去做吧

因此,这几乎是一个答案:

import mymodule
代码将“提前返回,如果不可用则中断执行”。唯一的问题是您不想看到错误消息

有两种方法可以解决这个问题


首先,您可以这样包装代码:

try:
    import mymodule
except ImportError:
    pass
else:
    # everything else you were going to do.
无论“代码”是整个函数体,还是调用函数的代码行,还是脚本或模块中的顶级代码块,或者其他什么,都没有区别


如果要避免额外的块缩进,可以通过各种不同的方式“提前返回”。(虽然实际上,将所有缩进的代码提取到一个新函数中几乎总是很简单的,这意味着您只需要在
else
块中调用一行函数即可。)

你如何做到这一点取决于你试图从哪个层次返回,而你的问题并不清楚。如果您想从函数中提前返回,只需返回(可能带有适当的值)。如果您想从整个程序中提前返回,只需
sys.exit(0)
。因此:

try:
    import mymodule
except ImportError:
    sys.exit(0)
# the rest of your code

您也可以使用正值退出,这是一种告诉shell或其他调用您的程序的人它“失败”的方法,而无需打印错误回溯。

我不确定这是否来得太晚,但我相信检查这一点的简单方法是使用
系统模块
dict:

import sys

if 'my_module' in sys.modules: 
    print ('Module available')
else:
    print ('Module not available')
如果要将其放入函数中:

import sys

def isavailable(m):
    if m in sys.modules: 
        return True
    else:
        return False

isavailable('mymodule')

这是您自己的模块,还是作为setuptools发行版安装的包的一部分?它是内置模块,但不是我的或python的。启动时加载的是应用程序自己的模块。好的,那么@kroolik的答案就是正确的。(对于setuptools包,最好检查
pkg\u资源。get\u distribution('foobar')
)没有理由这样做,而不仅仅是常规导入。您的答案还硬编码模块名称,并且问题并不表示模块名称需要动态。答案编辑,我以前版本的答案是针对这个版本的。
import\u如果可用(“namespace.package”)
-oops不起作用。这就是为什么你不应该使用,除非你真的知道自己在做什么。@LukasGraf现在呢?;)事实上,这不会导入模块吗?我想您可以定义一个函数来实现这一点,例如
def import\u avail(模块):try:\uu import\uu(模块),ImportError除外:return False,else:return True
,否则您会有一个很大的副作用@adsmith,您可以将
try:import except:else:
子句移动到
eval
中,并检查错误/前哨变量。是的,通过导入,您将自己暴露在模块init的副作用下,但是,我会重新评估是否使用在导入时引爆炸弹的模块。谢谢,顺便问一下,您知道我是否可以使用return停止执行?我不在函数中,但我希望后面的其余命令不被执行。我不知道我怎样才能修改你的代码来做到这一点。我想我可以把其余的代码封装在一个if语句中,但它很长。@JoanVenge,我会使用
raiseimportorror('Module`my_Module`不可用。')
并在导入模块中处理
importorror
,但这取决于您的用例。有时,您可能希望使用
my_module\u compat
模拟
my_module\u compat
当前面的模块不可用时,
尝试:导入除导入之外的my_module错误:将my_module\u compat导入为my_module
my_module\u compat
将实现my_module的noop变体,或者实现完全不同的实现。@kroolik:Why
raise ImportError(…)
?您只是在处理
importorror
时,用不同的消息引发了几乎相同的错误……与@Raydel的回答相同:
isavailable(“namespace.package”)