导入 Python 库并在它们不可用时优雅地处理
Posted
技术标签:
【中文标题】导入 Python 库并在它们不可用时优雅地处理【英文标题】:Importing Python libraries and gracefully handling if they are not availalble 【发布时间】:2013-12-12 03:26:18 【问题描述】:我想导入一堆库并捕获异常。
如果我只有 1 个 try catch 块,我会得到 1 个异常(第一个)。是否有一种模式可以遍历所有库并为每个缺少的库提供单独的异常?
#!/usr/bin/env python
try: import sys
except: print sys.exc_info()
try: import numpy as np
except: print sys.exc_info()
try: import scipy as sp
except: print sys.exc_info()
try: import os as os
except: print sys.exc_info()
try: from operator import itemgetter
except: print sys.exc_info()
try: import socket
except: print sys.exc_info()
try: import logging
except: print sys.exc_info()
try: from time import gmtime, strftime
except: print sys.exc_info()
【问题讨论】:
如果导入sys
失败,您的异常处理程序将完全失败。
我会在这里省略标准库。为什么导入这些文件根本会失败?
如果这些导入中的任何一个失败,为什么你的代码应该工作?您的代码是否足够健壮以处理未定义的 sp
或 np
?
正如 Martijn 正确指出的那样,这有点毫无意义。但是,如果您出于某种原因坚持不要在后续行中使用以前导入的模块(例如 sys
),因为它们可能尚未导入。
我不同意这里的评论者 - 有有效的用例。您可能会运行嵌入式 Python(如在应用程序或嵌入式设备中)而运行时受限,我遇到过这样的混蛋,例如在诺基亚 60 系列手机上。安息吧然而,在此处理仅用于找出您的应用程序在嵌入式设备上崩溃的原因,因为通常标准错误处理程序根本不输出任何内容。
【参考方案1】:
您可以使用__import__
动态导入模块,允许您通过迭代列表及其名称来导入模块。
例如:
libnames = ['numpy', 'scipy', 'operator']
for libname in libnames:
try:
lib = __import__(libname)
except:
print sys.exc_info()
else:
globals()[libname] = lib
您可以扩展它以处理 import ... as ...
和 from ... import ...
表单,或者稍后手动进行分配,即:
np = numpy
sp = scipy
itemgetter = operator.itemgetter
【讨论】:
我更喜欢这个解决方案,因为它使用基本的python,无需导入额外的库。【参考方案2】:虽然很常见,但不鼓励使用以下简单的设计模式及其变体:
# BAD, hides circular import etc. nested errors
try:
import moolib
except ImportError:
raise ImportError("You must install moolib from http://moo.example.com in order to run this app")
改为使用 Python 包管理器来检查库是否可用:
# GOOD
import pkg_resources
try:
pkg_resources.get_distribution('plone.dexterity')
except pkg_resources.DistributionNotFound:
HAS_DEXTERITY = False
else:
HAS_DEXTERITY = True
有关该主题的更多信息可以在这里找到
http://developer.plone.org/reference_manuals/external/plone.api/contribute/conventions.html#about-imports正如上面的 cmets 所指出的,Python 标准库模块 (stdlib) 始终可用,除非您在嵌入式环境中运行 Python,并且运行时已被剥离。
【讨论】:
链接说第一个版本不好,因为它可能隐藏循环导入错误。 请注意,虽然这里显示的第一个版本很糟糕,因为它可能会掩盖一些意想不到的东西,但提问者使用的原始版本却不是 - 它会打印发生的实际错误。 请注意,在 Python 3 上,重新引发 ImportError 时可能会嵌套错误。这不适用于 Python 2.x。【参考方案3】:您可以执行以下操作:
try:
import sys
import os.path
from logging import handlers
except ImportError as L_err:
print("ImportError: 0".format(L_err))
raise L_err
【讨论】:
以上是关于导入 Python 库并在它们不可用时优雅地处理的主要内容,如果未能解决你的问题,请参考以下文章
当没有可用的 javascript 时,在 drupal 中优雅地降级 jquery。想法?
如何优雅地将dat,txt 或者excel 文件导入python