学习python到现在,我们已经遇到过很多的报错信息,但一直没有认真研究,现在我们认真的研究一下:python一般会出现哪些错误呢?这些错误出现以后,我们该如何处理它们?
Python三种常见的错误类型
比如:
>>> for i in range(10)
File "" , line 1
for i in range(10)
^
SyntaxError: invalid syntax
>>>
上面那句话因为缺少冒号:,导致解释器无法解释,于是报错。这个报错行为是由 Python 的语法分析器完成的,并且检测到了错误所在文件和行号(File “”, line 1),还以向上箭头^标识错误位置(后面缺少:),最后显示错误类型。
当 Python 检测到一个错误时,解释器就无法继续执行下去,于是抛出异常。
系统会根据不同的异错误,丢出不同的异常。
异常种类繁多,现简要举例:
看一个异常(让0做分母了,这是小学生都相信会有异常的):
>>> 1/0
Traceback (most recent call last):
File "" , line 1, in <module>
ZeroDivisionError: division by zero
>>>
当 Python 抛出异常的时候,首先有“跟踪记录(Traceback)”,我们还可以给它取一个更优雅的名字——“回溯”。其后面显示异常的详细信息:比如异常所在位置(文件、行、在某个模块)。
最后一行是错误类型以及导致异常的原因。
下表中列出常见的异常
异常 | 描述 |
---|---|
NameError | 尝试访问一个没有申明的变量 |
ZeroDivisionError | 除数为0 |
SyntaxError | 语法错误 |
IndexError | 索引超出序列范围 |
KeyError | 请求一个不存在的字典关键字 |
FileNotFoundError | 文件未发现错误(比如你要读的文件不存在) |
AttributeError | 尝试访问未知的对象属性 |
ModuleNotFoundError | 模块未发现 |
IndentationError | 缩进 |
举例说明:
# NameError
>>> test
Traceback (most recent call last):
File "" , line 1, in <module>
NameError: name 'test' is not defined
# IndentationError
>>> a=123
File "" , line 1
a=123
^
IndentationError: unexpected indent
# IndexError
>>> a="abd"
>>> a[3]
Traceback (most recent call last):
File "" , line 1, in <module>
IndexError: string index out of range
# ZeroDivisionError
>>> 1/0
Traceback (most recent call last):
File "" , line 1, in <module>
ZeroDivisionError: division by zero
# AttributeError
>>> a=Car()
>>> a.color
Traceback (most recent call last):
File "" , line 1, in <module>
AttributeError: 'Car' object has no attribute 'color'
>>>
# ModuleNotFoundError
>>> import self_defin
Traceback (most recent call last):
File "" , line 1, in <module>
ModuleNotFoundError: No module named 'self_defin'
>>>
# KeyError
>>> dict={"name":"ws"}
>>> dict["age"]
Traceback (most recent call last):
File "" , line 1, in <module>
KeyError: 'age'
>>>
# FileNotFoundError
>>> a=open("w.txt","r")
Traceback (most recent call last):
File "" , line 1, in <module>
FileNotFoundError: [Errno 2] No such file or directory: 'w.txt'
>>>
# SyntaxError
>>> for i in rang
File "" , line 1
for i in rang
^
SyntaxError: invalid syntax
>>>
当我们在运行或者调试程序时遇到了异常,我们要学会阅读异常信息,找到出错的位置,发现异常,并更正它。比如用 dir()
,help()
或者官方网站文档、google 等来协助,一定能解决问题。
前面说,当 Python 检测到一个错误时,解释器就无法继续执行下去,于是抛出异常。
所以,在一段程序中,为了能够让程序健壮,必须要处理异常。
我们可以用try ... except
来处理异常,其语法格式如下:
try:
try_statements
except [Exception [as identifier]]:
except_statements
[else:
else_statements]
[finally:
fanally_statements]
举个例子,编程求X/Y。
>>> x = eval(input("请输入被除数x:\t"))
请输入被除数x: 10
>>> y = eval(input("请输入除数y:\t"))
请输入除数y: 2
>>> z = x/y
>>> print("x/y=",z)
以上编程运行结果:
#第一种
C:\Users\asus\Desktop\pythondemo测试\python运行程序>python band.py
请输入被除数x: 10
请输入除数y: 2
x/y= 5.0
#第二种
C:\Users\asus\Desktop\pythondemo测试\python运行程序>python band.py
请输入被除数x: 12
请输入除数y: 0
Traceback (most recent call last):
File "band.py", line 488, in <module>
z = x/y
ZeroDivisionError: division by zero
#第三种
C:\Users\asus\Desktop\pythondemo测试\python运行程序>python band.py
请输入被除数x: 12
请输入除数y: a
Traceback (most recent call last):
File "band.py", line 487, in <module>
y = eval(input("请输入除数y:\t"))
File "" , line 1, in <module>
NameError: name 'a' is not defined
#第四种
C:\Users\asus\Desktop\pythondemo测试\python运行程序>python band.py
请输入被除数x: 12,
请输入除数y: 1
Traceback (most recent call last):
File "band.py", line 488, in <module>
z = x/y
TypeError: unsupported operand type(s) for /: 'tuple' and 'int'
除去第一种以外,均抛出异常,退出程序。
捕捉以上程序中的异常1:
try:
x = eval(input("请输入被除数x:\t"))
y = eval(input("请输入除数y:\t"))
z = x/y
# except ZeroDivisionError:
# print("除数不能为0")
# except NameError:
# print("Name")
except (ZeroDivisionError,NameError,TypeError) as e:
print((type(e)),e)
print("程序可以正常运行")
现在用try…except改写,并捕捉相应的异常信息,并做出对应的处理,使程序不会因为异常而中断
捕捉以上程序中的异常2:
try:
x = eval(input("请输入被除数x:\t"))
y = eval(input("请输入除数y:\t"))
z = x/y
except ZeroDivisionError:
print("除数不能为0")
except Exception as e:
print(e.args)
else:
print("未捕捉到异常",z)
finally:
print("离开try...except 模块")
try…except小结
带有多个except的try语句z
try:
...
except exception1:
...
except exception2:
...
try:
...
except(exception1,exception2,...,)as e:
...
try:
...
except Exception as e:
...
try:
...
except:
...
除了系统抛出的异常,我们也可以使用raise语句自己触发异常。
raise语法格式如下:
raise [Exception [, args [, traceback]]]
比如
>>> raise NameError("Sorry,Error occurs")
Traceback (most recent call last):
File "" , line 1, in <module>
NameError: Sorry,Error occurs
>>>
也可以使用try…except来捕捉raise抛出的异常:
>>> try:
... raise NameError("Sorry,Error occurs")
... except NameError:
... print("捕捉到 NameError")
...
捕捉到 NameError
>>>
assert基本用法
assert condition
用来让程序测试这个condition,如果condition为false,那么raise一个AssertionError出来,逻辑上等同于:
if not condition:
raise AssertionError()
比如如下的例子:
>>> assert 1==1
>>> assert 1==0
Traceback (most recent call last):
File "", line 1, in
AssertionError
>>>
为assert断言语句添加异常参数
assert的异常参数,其实就是在断言表达式后添加字符串信息,用来解释断言并更好的知道是哪里出了问题。格式如下:
assert expression [, arguments]
比如:
>>> li=[1,2]
>>> assert len(li)>=5
Traceback (most recent call last):
File "" , line 1, in <module>
AssertionError 列表元素个数小于5
>>>
>>> assert 1==len(li)
Traceback (most recent call last):
File "" , line 1, in <module>
AssertionError 1不等于2
从上面的举例中可以基本了解了 assert 的特点。
assert,翻译过来是“断言”之意。assert 是一句等价于布尔真的判定,发生异常就意味着表达式为假。
assert 的应用情景就有点像汉语的意思一样,当程序运行到某个节点的时候,就断定某个变量的值必然是什么,或者对象必然拥有某个属性等,简单说就是断定什么东西必然是什么,如果不是,就抛出错误。
这就是断言 assert 的引用。什么是使用断言的最佳时机?有文章做了总结:
如果没有特别的目的,断言应该用于如下情况: