Python异常与断言

异常与断言

异常

“异常”通常被定义为“不符合规范的东西”但是在Python中,异常十分常见,简直到处都是。实际上,Python库中所有的模块都使用了异常

  • 我们经常将异常当做致命错误处理,异常发生时程序会终止,我们回到代码试图搞清楚为什么出错,程序因为一个异常被抛出而终止时,我们称程序抛出了一个未处理异常
  • 很多时候,异常是程序员应该预料到的事情,比如程序试图打开一个不存在的文件。

下面是一个典型异常的例子

1
2
3
4
5
SuccessNum = input('Enter SuccessNum: ')
totalNum = input('Enter totalNum: ')
ac = int(SuccessNum)/int(totalNum)
print('The AC ratio is',ac)
print('Now here')

该段程序在大多数情况下是运行良好的,但是如果用户输入中出现了0,(或者干脆直接跳过)程序就会崩溃,这显然不是我们乐意看到的
我们可以以下方式改写这段程序

1
2
3
4
5
6
7
8
9
10
try:
SuccessNum = input('Enter SuccessNum: ')
totalNum = input('Enter totalNum: ')
ac = int(SuccessNum)/int(totalNum)
print('The AC ratio is',ac)
except ZeroDivisionError:
print('Failure ! totalNum is 0')
except ValueError:
print('Error ! No input')
print('Now here')

try语句按照如下方式工作;

  • 首先,执行try子句(在关键字try和关键字except之间的语句)
  • 如果没有异常发生,忽略except子句,try子句执行后结束。
  • 如果在执行try子句的过程中发生了异常,那么try子句余下的部分将被忽略。如果异常的类型和 except 之后的名称相符,那么对应的except子句将被执行。最后执行 try 语句之后的代码。
  • 如果一个异常没有与任何的except匹配,那么这个异常将会传递给上层的try中。
    一个 try 语句可能包含多个except子句,分别来处理不同的特定的异常。最多只有一个分支会被执行。处理程序将只针对对应的try子句中的异常进行处理,而不是其他的 try 的处理程序中的异常。

异常的讨论

异常看上去不太友好(毕竟如果不处理程序会崩溃),但总好于其他方式。使用异常时,程序员需要编写一些代码来处理特定异常。如果忘记处理某个异常
那么这异常抛出时,程序便立刻停止。当然这也是好事,线性错误总好于隐士错误,我们来讨论BUG的问题。

  • 显性->隐性 显性错误有明显表现,如程序崩溃或运行时间长;隐性错误没有正常表现,程序正常结束,不会出任何问题–错了给出一个错误答案。
  • 持续->间歇 持续性错误在每次相同的运行输入时都会发生,间歇性错误仅在某些时候出现,即使是相同的输入和环境

显性错误和持续性错误是最好的,开发者不会对这种程序抱任何幻想,没有人愚蠢到使用这种程序。
优秀的程序员编写程序时,会尽量使程序时显性和持续性的,这种编程方式称为防御性编程

以隐性方式出错的程序特别危险,因为他们表面没有任何问题。人们使用它并对他产生依赖。逐渐的我们的人类社会将对软件产生依赖,这些软件来执行
超过人类能力的计算,我们甚至不能判断这些软件的计算是否正确。因此我们根本意识不到这个情况。这样的程序可能已经造成了严重危害。

断言

Python 语言为程序员提供了一种确保程序运行状态符合预期的简单方法。

1
2
3
def cal(num):
assert num>=0
return num**0.5