我们应该总是用一个try...except
块将编写的每个函数括起来吗?
我这样问是因为有时在一个函数中我们会引发Exception
,调用这个函数的调用方没有异常
def caller():
stdout, stderr = callee(....)
def callee():
....
if stderr:
raise StandardError(....)
然后我们的应用程序崩溃。在这个明显的例子中,我很想用try..except
将被调用方和调用方括起来。
但是我读了很多Python代码,他们并不是一直这样做的。
def cmd(cmdl):
try:
pid = Popen(cmdl, stdout=PIPE, stderr=PIPE)
except Exception, e:
raise e
stdout, stderr = pid.communicate()
if pid.returncode != 0:
raise StandardError(stderr)
return (stdout, stderr)
def addandremove(*args,**kwargs):
target = kwargs.get('local', os.getcwd())
f = kwargs.get('file', None)
vcs = kwargs.get('vcs', 'hg')
if vcs is "hg":
try:
stdout, stderr = cmd(['hg', 'addremove', '--similarity 95'])
except StandardError, e:
// do some recovery
except Exception, e:
// do something meaningful
return True
真正困扰我的是:
如果有第三个函数在其中一个语句中调用addandremove()
,我们是否也用try..except块包围调用?如果第三个函数有3行,并且每个函数调用本身都有一个try except,那会怎么样?我很抱歉把这事搞砸了。但这是我不明白的问题。
例外,顾名思义,是指在特殊情况下,不应该发生的事情
…而且因为它们可能不应该发生,在很大程度上,你可以忽略它们。这是件好事。
有时您会执行操作,但特定异常除外,例如,如果执行以下操作:
在这种情况下,可以合理地预期“无法联系服务器”错误,因此您可能会:
然而,试图抓住每一个可能的错误都是徒劳的——有无数的事情可能会出错。。作为一个奇怪的例子,如果一个模块修改了
urllib2
并删除了urlopen
属性怎么办-没有合理的理由期望NameError
,也没有合理的方法可以处理这样的错误,因此您只需让异常向上传播让代码以回溯的方式退出是一件好事——它允许您轻松地看到问题的来源和原因(基于异常和它的消息),并修复问题的原因,或者在正确的位置处理异常。。。
简而言之,只有当可以对异常进行有用的处理时,才能处理异常。如果没有,尝试处理所有无数可能的错误只会使您的代码更麻烦,更难修复
在您提供的示例中,try/except块什么也不做—它们只是重新引发异常,因此它与更整洁的块相同:
关于与异常处理相关的惟一事情,我可能希望处理的是,如果找不到'hg'命令,则生成的异常并不是特别具有描述性。所以对于一个图书馆,我会做一些类似的事情:
这只是在更清晰的“CommandNotFound”中包装了可能令人困惑的“OSError”异常。
重读这个问题,我怀疑您可能误解了Python异常是如何工作的(“调用此函数的调用方没有异常”位,所以希望澄清一下:
调用方函数不需要知道可能从子函数引发的异常。你可以调用
cmd()
函数并希望它能正常工作。假设您的代码位于一个
mystuff
模块中,并且其他人想要使用它,他们可能会:或者,如果用户没有安装
hg
,他们可能希望给出一个很好的错误消息并退出:try
/except
子句只有在知道如何处理引发的错误时才真正有用。执行以下程序:但是,您可能具有以下功能:
用户可以尝试将其用作:
用户可以将其放入try/except块中,但随后
my_new_list
将不会被定义,可能只是稍后引发异常(可能是NameError)。在这种情况下,由于回溯中的行号/信息指向一段并非真正问题的代码,因此会使调试变得更困难。您应该使用try-catch块,以便可以明确定位异常的源。你可以把这些块放在任何你想要的地方,但是除非它们产生一些有用的信息,否则没有必要添加它们。
相关问题 更多 >
编程相关推荐