Python中ZeroDivisionError的好处

时间:2015-09-14 14:16:20

标签: python

假设我有两个变量x& y,可以是任何值。我必须将x除以y。 y可以为零。现在我有两种方法

1)

if y == 0:      
    continue # or break, supposing there is a loop going on.

2)

try:
    print 1/0
except ZeroDivisionError as e:
    print e
finally:
    print "got"

我的问题是,方法2是否比方法1有任何好处,如果是,那么它是什么?

2 个答案:

答案 0 :(得分:2)

try / except可能be slightly faster

一般来说," Pythonic方式"是尝试做你想做的事情并处理错误,如果它不起作用(" Easier to Ask Forgiveness than Permission"),而不是预先检查(" { {3}}"),以便在将来提供更大的灵活性。

似乎y通常是代码中的整数(int的实例)..但想象一下您的需求在不断变化,yNewClass的实例现在可以保存-0.0001之类的值。

为了保持与您的应用程序的兼容性,编写了NewClass.__eq__(),以便if y == 0进行整数比较(在此实例中为True ),但NewClass.__truediv__使用浮点值,因此1 / y不会返回错误。

因此,如果您使用if,您的应用将采用-0.0001 == 0,而使用except ZeroDivisionError则会正确处理新行为。

class NewClass(int):
    def __eq__(self, other):
        return int(self) == int(other)
    def __truediv__(self, other):
        return self.value / other

y = NewClass(-0.0001)

if y != 0:
     print 1 / y  # not printed

try:
    print 1 / y  # printed
except ZeroDivisionError:
    pass

答案 1 :(得分:1)

从绩效的角度来看,我会说选项2是否比选项1有任何好处取决于y为0的频率。

如果y为0是常见的,那么选项2将不太可取,因为它最终会频繁地提高ZeroDivisionError,而执行if y == 0:if y != 0:检查会更少耗时。

但是如果y很少为0(这是一个异常情况),那么选项2会更优选,因为你没有进行if检查的开销,并且很少会引发错误

计时示例 -

In [4]: def func2(lst):
   ...:     for i in lst:
   ...:         try:
   ...:             x = 10/i
   ...:         except ZeroDivisionError:
   ...:             pass
   ...:

In [5]:

In [5]: def func1(lst):
   ...:     for i in lst:
   ...:         if i != 0:
   ...:             x = 10/i
   ...:

In [6]: lst1 = [0 for i in range(100)]

In [7]: import random

In [8]: lst2 = [random.randrange(0,5) for i in range(100)]

In [9]: lst3 = [random.randrange(0,15) for i in range(100)]

In [10]: lst2.count(0)
Out[10]: 24

In [11]: lst3.count(0)
Out[11]: 5

In [12]: %timeit func1(lst1)
100000 loops, best of 3: 3.56 µs per loop

In [13]: %timeit func2(lst1)
10000 loops, best of 3: 50.6 µs per loop

In [14]: %timeit func1(lst2)
100000 loops, best of 3: 7.73 µs per loop

In [15]: %timeit func2(lst2)
10000 loops, best of 3: 18 µs per loop

In [16]: %timeit func1(lst3)
100000 loops, best of 3: 8.76 µs per loop

In [17]: %timeit func2(lst3)
100000 loops, best of 3: 9.88 µs per loop

即使只有5%的数字为0,if循环仍然比try/except块更高效。

基本上,例外情况应该是特殊情况。