python提供什么机制处理程序运行错误_python异常处理

在本文中我会介绍关于在Python中如何处理各种错误异常。首先我们来看一下我们在上一篇中拟定的学习计划,加粗体代表我们已经介绍的内容,斜体代表新增内容。

20200321084851655.jpg

异常处理

文件的读写

正则表达式

操作文件和目录

深拷贝和浅拷贝

面向对象的编程

变量(扩展介绍)

二进制、八进制和十六进制(包括ASCII)

迭代、生成和递归

高阶函数map

匿名函数lambda

图像处理(运用numpy)

2. 异常类型

异常有各种各样,比如我们输入

a = 1 / 0

肯定是会报错的,0不能作为除数,还比如:

a = [0, 1, 2, 3, 4, ]

a[100]

也肯定会报错,因为这个数列压根就没有第100位。

报错的时候,我们通常会看到PyCharm下面运行区内红红的一堆字提示错误。

我们能见到的异常类型有各种各样,

BaseException

+-- SystemExit

+-- KeyboardInterrupt

+-- GeneratorExit

+-- Exception

+-- StopIteration

+-- StopAsyncIteration

+-- ArithmeticError

| +-- FloatingPointError

| +-- OverflowError

| +-- ZeroDivisionError

+-- AssertionError

+-- AttributeError

+-- BufferError

+-- EOFError

+-- ImportError

| +-- ModuleNotFoundError

+-- LookupError

| +-- IndexError

| +-- KeyError

+-- MemoryError

+-- NameError

| +-- UnboundLocalError

+-- OSError

| +-- BlockingIOError

| +-- ChildProcessError

| +-- ConnectionError

| | +-- BrokenPipeError

| | +-- ConnectionAbortedError

| | +-- ConnectionRefusedError

| | +-- ConnectionResetError

| +-- FileExistsError

| +-- FileNotFoundError

| +-- InterruptedError

| +-- IsADirectoryError

| +-- NotADirectoryError

| +-- PermissionError

| +-- ProcessLookupError

| +-- TimeoutError

+-- ReferenceError

+-- RuntimeError

| +-- NotImplementedError

| +-- RecursionError

+-- SyntaxError

| +-- IndentationError

| +-- TabError

+-- SystemError

+-- TypeError

+-- ValueError

| +-- UnicodeError

| +-- UnicodeDecodeError

| +-- UnicodeEncodeError

| +-- UnicodeTranslateError

+-- Warning

+-- DeprecationWarning

+-- PendingDeprecationWarning

+-- RuntimeWarning

+-- SyntaxWarning

+-- UserWarning

+-- FutureWarning

+-- ImportWarning

+-- UnicodeWarning

+-- BytesWarning

+-- ResourceWarning

这些都是在官网文档上复制粘贴下来的,这里面的比如NameError,指的是我们用了没有定义的变量名,FileNotFoundError指的是要读取的文件不存在,ZeroDivisionError指的是我们除以了一个零。大家可以点击下面的链接来了解各种错误异常。

3. 处理异常

如果我们的代码有错,程序就会在遇见第一个错误时报错并停止运行,为了让程序能够平稳运行,不被错误所打扰,这里我们需要知道如何处理:

try:

# Your code

except:

# What to do with the exception/error

我们需要在我们可能产生错误的代码外面套上try…except语句。try下面直接写上我们原先的代码,except下面写上我们如果遇到程序异常后该怎么做,这样的话我们程序就能遇到错误后依旧平稳运行。

while True:

try:

x = int(input('Please enter a number: '))

break

except:

print('That was no valid number.')

我们运行这段代码,我们可以看到如果我们输入不是整数的话,就会输出except下面的那句话,但是程序并没有“异常终止”,如果我们输入的是整数的话,程序就会安静地运行结束。

可以看到,错误产生时while循环并未被break打断,可以得知异常被捕捉到后马上就会忽略之后的内容,并且直接跳至except。

当然我们可以更清晰一点:

while True:

try:

x = int(input('Please enter a number: '))

break

except ValueError:

print('That was no valid number.')

因为int后面的不能转换为整数时会归为ValueError。如果我们不知道是何种异常时,我们操作方法可以是:

只写except,

运行没有try…except的语句,故意输入错误,看红字显示是什么再回来改

用Exception代替所有可能性,如下

while True:

try:

x = int(input('Please enter a number: '))

break

except Exception:

print('That was no valid number.')

当然,你也可以用BaseException,这里要知道所有的基本错误都归于BaseException下,且绝大部分错误是归于Exception下的。

4. 多种异常

当然,我们的代码有时候会因各种原因碰见多种异常,比如

while True:

try:

x = int(input('Please enter a number: '))

print(100 / x)

break

except Exception:

print('Some error occurred.')

如果用户输入非整数,就会跑except去,如果用户输入是0,0不能做除数,也会跑except去。这是我们可以这样:

while True:

try:

x = int(input('Please enter a number: '))

print(100 / x)

break

except ValueError:

print('That was no valid number.')

except ZeroDivisionError:

print('100 / 0 is invalid.')

这样我们就能在运行时区分到底错在哪里了。当然由于try发现异常后会去找第一个能处理此异常的except,在这里两个except不相关,能交换位置。

而下面的代码:

while True:

try:

x = int(input('Please enter a number: '))

print(100 / x)

break

except Exception:

print('Exception!')

except ValueError:

print('That was no valid number.')

except ZeroDivisionError:

print('100 / 0 is invalid.')

这里它只会看第一个except,发现错误后永远只会输出Exception,原因是Exception包含了ValueError和ZeroDivisionError,try发现异常后看到第一句except能处理,就把异常交给第一个except,自动忽略后面的。

我们还可以如此处理多种异常:

while True:

try:

x = int(input('Please enter a number: '))

print(100 / x)

break

except (ZeroDivisionError, ValueError):

print('Exception!')

用括号括起来,里面能写几个写几个,这样的话我们如果遇见括号里面任意一种异常,就能运行此except。

5. 异常所携带的信息

通常异常中会带有信息,我们可以赋予异常一个变量名以输出具体信息:

while True:

try:

x = int(input('Please enter a number: '))

print(100 / x)

break

except (ZeroDivisionError, ValueError) as e:

print(e)

当然不一定非得命名为e,如果我们输入0,则会输出:

division by zero

而如果我们输入非整数,而是其他字符的话,比如我输入了apple,则会输出:

invalid literal for int() with base 10: 'apple'

这些都是这写异常所携带的信息。

6. finally和else语句

while True:

try:

x = int(input('Please enter a number: '))

print(100 / x)

break

except (ZeroDivisionError, ValueError) as e:

print(e)

finally:

print('Goodbye!')

也就是说不管有没有错,在运行完上述的代码后,一定会执行finally内部的代码。如果我们输入的是0或者非整数,会输出错误信息后带着输出Goodbye然后继续循环会try,如果我们输入正确,运行没有错,while True被break顺利终止了,还是会继续finally内部的代码,输出Goodbye。

while True:

try:

x = int(input('Please enter a number: '))

print(100 / x)

except (ZeroDivisionError, ValueError) as e:

print(e)

else:

print('Goodbye!')

break

else语句只有在try下面没有错的情况下才会运行,注意我把break移到else下面了,我们可以把它看作是try内部内容的延伸。

7. raise语句

当然,我们在自己写码的时候,也会需要在某些场合输出异常。比如我们认为负整数不是整数,那么输入后,我们可以手动输出此异常。

while True:

try:

x = int(input('Please enter a number: '))

if x < 0:

raise ValueError

break

except ValueError as e:

print(e)

但是由于这个ValueError是我们自己输出的,这么写我们并不会看到其携带信息,我们可以这么做让其携带自定义信息:

while True:

try:

x = int(input('Please enter a number: '))

if x < 0:

raise ValueError('Negative number is not allowed')

break

except ValueError as e:

print(e)

输出测试:

Please enter a number: y

invalid literal for int() with base 10: 'y'

Please enter a number: -9

Negative number is not allowed

Please enter a number: 0

输入0,没有错误,程序顺利结束。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值