Python学习笔记(13)——try...except...容不得你在这儿撒野!
开始之前,我来提问一下:
请问下面这段代码错误嘛?
print(哈哈哈!!!)
答:这段代码是错误的。
它放到解释器里会报错:
File "xxx.py", line 1
print(哈哈哈!!!)
^
SyntaxError: invalid character in identifier
但是我们如果这样写:
print('哈哈哈!!!')
他就会成功显示:哈哈哈!!!。
上面有一个错误,你发现没有?
但那仅仅是错误(SyntaxError一般情况下全是错误),我们要研究的是异常:
>>> int('哈哈哈哈') # Python无法把'哈哈哈哈'转换为整数,所以会报错。
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
int('哈哈哈哈')
ValueError: invalid literal for int() with base 10: '哈哈哈哈'
或者:
>>> 'abc' + 12 # 请问你觉得整数加字符串,和是什么?
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
'abc' + 12
TypeError: can only concatenate str (not "int") to str
你发现规律了嘛?
Traceback (most recent call last):
File "python文件", line 所在行, in 类或函数
# 我是错误代码
... # 接下来还会一直追到错误的鼻祖
我是异常: 我是错误原因
咱们来解读一下。
Traceback (most recent call last):Traceback相当于你逛淘宝时的追溯源,会从错误处一直跑到错误的鼻祖(主要错误原因),最终解读程序的异常。
File "python文件", line 所在行, in 类或函数:错误在哪儿?这玩意儿可以告诉你。
# 我是错误代码:你错哪儿了?这玩意儿可以告诉你。(有时还会有一个小箭头跟随)
...:前面说了,Traceback会从错误处一直跑到错误的鼻祖。
我是错误: 我是错误原因:没有这行的话,你咋改都不知道。
那怎么拦截呢?
现在进入重点——
1.拦截错误
拦截错误就是利用try...except...finally...else...的组合拳,不让程序报错。
比如:
>>> try:
... int('哈哈哈哈')
... except:
... print('警告!你被绿了!')
...
警告!你被绿了!
哈哈哈哈,开个玩笑。
格式为:
try:
# 我是错误代码
except 我是大名鼎鼎的错误 as 我是错误的赋值变量: # except可以不执行(除非finally或else不执行)
# 我是一脚踢死你的代码
finally: # finally可以不执行(除非except执行)
# 我是死皮赖脸非得执行的代码
else: # else可以不执行(除非except执行)
# 我是不错误就执行的代码
看着是不是和Java的try...catch...非常相似呢?
try {
// 我是错误代码
} catch(我是大名鼎鼎的错误 我是错误的赋值变量) {
// 我是一脚踢死你的代码
}
依然解读一下。
try:这里放上(容易)错误的代码。
except:关于错误的处理语句。
finally:无论如何都会执行。
else:只有不错误才能执行。
比如:
try:
i = 'abc' + 1
except TypeError:
print('字符串不能与整数相加')
'''
字符串不能与整数相加
'''
看起来是不是很爽呢。
有一点需要提醒:只有继承
Exception的类(继承见Python学习笔记(10)——我的爸爸的爸爸的爸爸的爸爸……)才可以拦截。反正我是写了一家伙,还没写完就报错了。(⊃・ᴥ・)つ
下面来看一个有点精神病的关键词:raise。
2.raise——报错的罪魁祸首
raise会自己抛出错误,所有报错都是因为它。
这个精神病的用法如下:
raise 我是大名鼎鼎的错误(我是它的参数)
我是大名鼎鼎的错误:错误的名字。
我是它的参数:错误类的参数,一般第一个是描述。
比如有一段代码:
>>> def more(x,y):
... if y == 0:
... raise ZeroDivisionError('任何数除以0都没有意义')
... else:
... return x/y
...
>>> more(1,0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
more(0,1)
File "<stdin>", line 3, in more
raise ZeroDivisionError('任何数除以0都没有意义')
ZeroDivisionError: 任何数除以0都没有意义
为什么拦截住错误不是print,而是raise呢?这不是神经病是啥?
其实这种情况很常见,用raise把一个错误向上抛,最高的管理层(即调用参数的地方)就可以轻松地用try...except...组合拳拦截住。否则,要是你来一个print,你难道还用stringio拦截?!真是小题大做!!!
stringio我们接下来会讲。
好的,今天的文章就到这里。
散会~

