更好地“尝试”一些东西,并捕捉exception或testing是否可能首先避免exception?
我应该testing一下是否有效,或只是try
去做,并捕获exception?
- 有没有可靠的文件说有一种方法是优先的?
- 是一种更pythonic ?
例如,我应该:
if len(my_list) >= 4: x = my_list[3] else: x = 'NO_ABC'
要么:
try: x = my_list[3] except IndexError: x = 'NO_ABC'
有些想法…
PEP 20说:
错误不应该默默通过。
除非明确沉默。
应该使用一个try
而不是一个if
被解释为一个错误地传递的错误? 如果是这样,你是否明确地使用这种方式来消除它,因此,它可以吗?
我不是指只能做1件事情的情况; 例如:
try: import foo except ImportError: import baz
你应该更喜欢try/except
结果是if/else
- 加速(例如通过防止额外的查找)
- 更干净的代码(less线/更易于阅读)
这些经常是相辅相成的。
速度起坐
在通过以下方式尝试在长列表中查找元素的情况下:
try: x = my_list[index] except IndexError: x = 'NO_ABC'
尝试,除了是index
可能在列表中的最佳选项,通常不会引发IndexError。 这样,您可以避免通过if index < len(mylist)
进行额外的查找。
Python鼓励使用exception, 您处理的是从Dive Into Python开始的一个短语。 你的例子不仅处理exception(优雅),而不是让它静静地通过 ,也只有在例外的情况下才会发现exception (因此这个词是exception !)。
更干净的代码
官方的Python文档提到了EAFP : 比权限更容易要求原谅 , Rob Knight指出, 捕获错误而不是避免错误会导致更清晰,更易读的代码。 他的例子是这样说的:
更糟糕的是(LBYL'看你跳跃') :
#check whether int conversion will raise an error if not isinstance(s, str) or not s.isdigit: return None elif len(s) > 10: #too many digits for int conversion return None else: return int(str)
更好(EAFP:容易要求宽恕比权限) :
try: return int(str) except (TypeError, ValueError, OverflowError): #int conversion failed return None
在这种情况下,你应该完全使用其他的东西:
x = myDict.get("ABC", "NO_ABC")
但是,一般来说,如果您希望testing经常失败,请使用if
。 如果testing相对于仅仅尝试操作而言是昂贵的并且如果失败则捕获exception,则使用try
。 如果这些条件中没有一个适用,那么更简单地去阅读。
如果在你做这件事之前检查是否会失败,那么你应该赞成。 毕竟,构造exception(包括其相关的回溯)需要时间。
例外情况应该用于:
- 意想不到的事情,或…
- 你需要跳过多于一个逻辑层次的事情(例如,
break
不够多),或者… - 事情你不知道什么是要提前处理例外,或…
- 事先检查失败的东西是昂贵的(相对于只是尝试操作)
请注意,通常情况下,真正的答案是“既不” – 例如,在第一个示例中,您应该做的只是使用.get()
来提供默认值:
x = myDict.get('ABC', 'NO_ABC')
如果有任何可能的比赛条件,应该使用try
和except
直接而不是内部。 例如,如果你想确保一个目录存在,不要这样做:
import os, sys if not os.path.isdir('foo'): try: os.mkdir('foo') except OSError, e print e sys.exit(1)
如果另一个线程或进程在isdir
和mkdir
之间创build目录,则会退出。 相反,这样做:
import os, sys, errno try: os.mkdir('foo') except OSError, e if e.errno != errno.EEXIST: print e sys.exit(1)
只有当'foo'目录不能创build时才会退出。
应该使用一个try而不是一个if被解释为一个错误地传递的错误? 如果是这样,你是否明确地使用这种方式来消除它,所以它可以吗?
使用try
是承认错误可能会通过,这是相反的,它通过默默。 使用except
导致它不能通过。
使用try: except:
在if: else:
逻辑比较复杂的情况下更好。 简单胜于复杂; 复杂比复杂好; 请求宽恕比容许更容易。
什么“错误不应该默默地传递”是警告,代码是否可以引发你所知道的exception,以及你的devise承认了这种可能性的情况,但是你没有devise出处理exception的方法。 在我看来,明确地沉默一个错误,就是做一个类似于pass
一个except
块的东西,这只能通过理解“无所事事”确实是在特定情况下正确的error handling来完成。 (这是几次我觉得在写好代码的评论可能真的需要的时候。
但是,在您的具体示例中,两者都不合适:
x = myDict.get('ABC', 'NO_ABC')
每个人都在指出这一点 – 即使你承认你一般的理解欲望,无法提供一个更好的例子 – 在相当多的情况下实际上存在着相同的边际步骤,寻找它们是解决问题的第一步。
正如其他post所说,这取决于情况。 使用try /有几个危险,除了提前检查数据的有效性,特别是在大型项目中使用时。
- try块中的代码可能有机会在exception被捕获之前发生各种各样的破坏 – 如果你事先用if语句预先检查,你可以避免这种情况。
- 如果在你的try块中调用的代码引发了一个常见的exceptiontypes,比如TypeError或者ValueError,那么你可能实际上并没有捕获到你期望捕获的同样的exception – 甚至可能在别人之前或之后引发同样的exception类可能会引发exception的行。
例如,假设你有:
try: x = my_list[index_list[3]] except IndexError: x = 'NO_ABC'
IndexError没有说明是否在尝试获取index_list或my_list的元素时发生。
对于一般的含义,你可以考虑阅读Python中的习语和反习语:例外 。
正如其他人所说,在你的特定情况下,你应该使用dict.get()
:
get(key [,default])
如果键在字典中,则返回键的值,否则返回默认值。 如果没有给出默认值,它默认为None,所以这个方法永远不会引发KeyError。
- 抛出HttpResponseException或返回Request.CreateErrorResponse?
- ASP.NET Core Web APIexception处理
- Python当我发现exception时,如何获取types,文件和行号?
- 找出一个方法可能抛出的exceptionC#
- 有没有一种pythonic的方式来尝试一些最多的次数?
- 当.NET抛出WebException((400)Bad Request)时如何处理WebResponse?
- 在Python中使用try-except-else是一个好习惯吗?
- 我如何处理Python中的列表理解exception?
- 在XML预览呈现问题:无法定位模式0