-1

我构建了这两个代码,我想知道哪个更好。由于这不是我的程序所关心的,所以我并不一定意味着哪一个更快执行。哪一个更具可读性?Python:哪个代码更好?

或者:

A = 1 
B = some_other_value 
try: 
    A /= B 
except ZeroDivisionError: 
    pass 

或者:

A = 1 
B = some_other_value 
if B != 0: 
    A /= B 
+1

**既不是**,因为这两个代码位有效地隐藏了计算出现问题的事实。 –

+1

重复的:http://stackoverflow.com/questions/1835756/using-try-vs-if-in-python – Wessie

+1

python使用异常流控制的事实并不意味着你应该只使用异常流控制。 – mishik

回答

1

当然第二个:

A = 1 
B = some_other_value 
if B != 0: 
    A /= B 

不是因为它更具可读性,但因为你没有使用一个例外非特殊情况。如果无效输入或在正常情况下可能导致错误的输入是可能的,那么您绝不应该使用异常来处理它。

你可以找到(旁边性能)关于这个网络上,但在我看来很不错的解释总是因为意图的:当你处理异常,那么你明确地告诉读者,这是一个异常情况,一个错误,这在正常的程序流程中不应该发生。在你的情况这不是因为一个无效的输入是绝对可能的(每个输入必须被验证,总是)

从我的角度来看,你想要处理它的事实意味着这是可能的,然后检查总是正确的解决方案。就像Ryan所说的,如果你不需要检查零值,你可能会有更高的多态性,那么你需要做的是移动支票来处理这种情况(例如在/运算符中,而不是在你使用它的地方)。

编辑
很少有词汇可以总结我写的评论。 Python鼓励一种名为EAFP的编程风格,当你编写小脚本时,这是一个很好的资源,但在编写应用程序和库时应该谨慎使用它。

它有助于保持码短(和快速为最常见的代码路径),但它有一个大缺点:如果你不try/execpt包装每个几行你会必须处理中间结果和部分计算。一个大的try可能会使应用程序处于不确定状态(否则它会使您的代码更不易读,因为长列表可能是嵌套的 - try/except/else/finally)。

我同意它有助于使用你的代码的情况下,你甚至没有去想但这不灵活,这是脆弱。对于简短的个人脚本也许可以,但是如果我编写一个应用程序(或者甚至更多的库),我想确定我的代码在哪里以及如何失败,我会编写测试以检查它如何与不同的输入一起工作。我不希望它会以我无法预知的方式失败,意外的输入>意外的行为听起来太像垃圾输入>垃圾输出。应用程序必须健壮。在你检查完你可以检查的所有东西之后,你甚至必须为异常情况做好准备(我可以放松这个规则,以便检查可能是偏执的)。

+0

除以零并不例外? –

+0

@HunterMcMillen **不,它不是**,因为输入必须总是**验证**,特别是如果你认为它可能发生(除了块以外的空白让我认为他们必须是)。 –

+2

@Adriano EAFP更加pythonic,输入验证通常是不鼓励的。而且你需要在此之上进行类型测试来实际验证输入,这很少被鼓励。 –

1

第二个可能更具可读性,但第一个允许更大的多态性和鸭子打字(在B不是floatint,但是支持除法的对象)的情况下。

大多数讨论在这里似乎是缺少点B可能是支持部门自定义对象。请考虑下面的例子,其中NumType作为分母。

>>> class NumType(object): # basically, an int wrapper 
...  """Custom number type. Supports division when it is the denominator""" 
...  def __init__(self, val):    
...    self.val = val 
...  def __rdiv__(self, num): 
...    return num/self.val 
... 
>>> c = NumType(1) #normal division works as expected 
>>> 5/c 
5 
>>> c = NumType(7) 
>>> 5./c 
0.7142857142857143 
>>> c = NumType(0) 
>>> 5/c # 0 division causes exception 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 5, in __rdiv__ 
ZeroDivisionError: integer division or modulo by zero 
>>> # pay attention here: 
>>> if c != 0: # condition is True because c is an object, not 0 
...  print 5/c # so this division still occurs, and generates an exception 
... 
Traceback (most recent call last): 
    File "<stdin>", line 2, in <module> 
    File "<stdin>", line 5, in __rdiv__ 
ZeroDivisionError: integer division or modulo by zero 
>>> # however, this is caught with a try/except 
>>> try: 
...  5/c 
... except ZeroDivisionError: 
...  print '0 division' 
... 
0 division 
0

答案是:取决于。

您是否可以轻松编写适当的测试来处理条件。在这种情况下,你可以。

另一个考虑因素是你的手写测试是否足够。在一行代码中,这很容易。如果你有很多操作,假设一切都很好,并且事后弄清楚,例外情况可能更有意义。 (当然,在这种情况下,输入验证通常会更有用)。

与编程中的大多数事情一样,这是风格和品味的问题。在python中尤其如此,python通常具有多种处理方式(尽管你可能已经阅读过任何复活节彩蛋),而且它主要基于程序员能够做出自己的决定的想法(不像Java,确实试图强制执行一种编程风格,通过使所有事情都比预期的技术更难以且更令人不快)。

想想你在做什么,为什么。尽量不要重复自己。