捕获Python异常并打印出单独的消息
我目前正试图编写代码来捕获异常,根据引发的异常,将导入与未引发异常时不同的模块捕获Python异常并打印出单独的消息,python,python-2.7,exception,exception-handling,drmaa,Python,Python 2.7,Exception,Exception Handling,Drmaa,我目前正试图编写代码来捕获异常,根据引发的异常,将导入与未引发异常时不同的模块 try: import sge_execution_engine as execution_engine except ImportError: print "Use local execution engine because SGE support is missing!" print sys.exc_info() # Print out the exception message import
try:
import sge_execution_engine as execution_engine
except ImportError:
print "Use local execution engine because SGE support is missing!"
print sys.exc_info() # Print out the exception message
import local_execution_engine as execution_engine
except RuntimeError:
print "Using local execution engine because SGE support is missing!"
print sys.exc_info()
import local_execution_engine as execution_engine
捕获的第一个异常,ImportError
捕获在执行import sge\u execution\u engine
期间找不到pythondrmaa
模块时引发的异常(在sge\u execution\u engine
内部,有一条import drmaa
语句)。第二个异常是RuntimeError
,当发现drmaa
python库时(比如执行sge\u执行引擎中的import drmaa
语句时),会捕获该异常,但操作系统中没有安装drmaa
C库。我们希望这两条except
语句足以捕获当用户试图在没有pythondrmaa
库、drmaa
C库或未安装Sun Grid Engine的机器上运行此模块时可能引发的所有异常。在没有任何这些过程的情况下,模块继续进行导入本地执行引擎,这样代码就可以在用户的机器上本地执行。现在,代码的工作方式与预期的一样,即当它发现sge异常时,它将导入本地,但我们仍希望改进这里的异常处理,使其更加健壮
在我看来,我认为将抛出的实际异常消息打印到stdout是一件好事,因为它可以让用户知道为什么他无法导入sge_execution_引擎,尤其是在他不希望导入失败的情况下
但是,不是使用print sys.exc_info()
在屏幕上打印实际的异常消息,我意识到也许更好的方法是使用EXCEPTION作为某个变量名
格式,然后打印出print some变量名
,还调用与抛出并分配给some变量名
的异常相关联的一些属性
我看到这是在有这段代码的地方做的:
import sys
try:
f = open('myfile.txt')
s = f.readline()
i = int(s.strip())
except IOError as e:
print "I/O error({0}): {1}".format(e.errno, e.strerror)
except ValueError:
print "Could not convert data to an integer."
except:
print "Unexpected error:", sys.exc_info()[0]
raise
似乎except IOError as e
区块通过专门调用IOError
对象的errno
和strerror
属性,以细粒度方式处理异常消息。但是,当我查看IOError
时,我没有看到这些特定属性作为异常文档的一部分列出。事实上,Python文档下的所有其他异常也是如此,因此我们似乎无法确定哪些属性将与特定异常关联。如果我们对此一无所知,那么当我们使用import异常作为some-variable\u name
语法来处理我们的异常时,我们将如何找出调用some-variable\u name
对象的哪些属性
我会很感激任何人对这一点的建议,即使你的回答不是直接回答我的问题,但如果你有另一个完全不同的建议,我可以更好地处理我的例外情况,请不要犹豫发表一篇文章
多谢各位 首先,您认为最好将异常捕获到变量中,而不是忽略它,然后使用sys.exc\u info()
将其拉出。使用exc_info
(低级代码,必须同时使用2.6和3.x之前版本的代码,等等)有一些很好的理由,但一般来说,当您能够按自己的方式完成时,您应该这样做
这甚至适用于你最后的裸体。在2.7中,普通的Exception:
与Exception:
的意思相同,因此您可以将Exception写为e:
,然后使用e
值
另外请注意,如果您想对多个异常类型执行完全相同的操作,则可以将编写为e:
,除了(RuntimeError,ImportError)
至于“让它更健壮”,这不是绝对的事情。例如,如果出现一些既不是运行时错误
也不是导入错误
的意外异常,您是要记录该异常并尝试使用回退代码,还是完全停止并转储回溯?例如,如果它是由某人签入程序的错误编辑导致的SyntaxError
,您可能不想将其视为运行时错误……或者您确实想这样做;这实际上取决于您的开发实践和目标用户群
同时:
似乎except IOError as e
区块通过专门调用IOError
对象的errno
和strerror
属性,以细粒度方式处理异常消息。但是,当我查看时,我没有看到这些特定属性作为异常文档的一部分列出
你需要查一下表。请注意,IOError
是的子类,它记录了errno
和strerror
属性。(这些属性的实际含义仅记录了OSError
及其子类,但它们存在的事实已被记录。)
如果你认为这一切都有点混乱…嗯,是的。在Python3.x中,这一切都得到了清理,IOError
和EnvironmentError
被合并到OSError
中,后者清楚地记录了它的属性,通常不必首先打开errno
,因为commonerrno
值会生成一个特定的子类,如FileNotFoundError
,等等。但是,只要您使用2.7,您就不会从过去6年对该语言的改进中获益
例如
try:
i = int(s, 16)
except ValueError as e:
print '{} is not a base-16 number'.format(s)
try:
import sge_execution_engine as execution_engine
except:
print "Use local execution engine because SGE support is missing!"
print sys.exc_info() # Print out the exception message
import local_execution_engine as execution_engine
import logging
logger = logging.getLogger()
logger.setLevel(logging.WARNING)
logger.exception('unable to import sge')