语法错误
如下,当我们编写的代码中出现语法错误的时候,Python 解析器会报这类的错误。
>>> while True print('Hello world')
File "<stdin>", line 1
while True print('Hello world')
^
SyntaxError: invalid syntax
2
3
4
5
异常
在程序运行过程中,难免会出现异常。下面展示了几种运行时异常。
>>> 10 * (1/0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
>>> 4 + spam*3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'spam' is not defined
>>> '2' + 2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't convert 'int' object to str implicitly
2
3
4
5
6
7
8
9
10
11
12
处理异常
我们通过 try
语句来处理异常,完成的使用方法如下:
try:
<statement-1>
.
.
<statement-N>
except Exception as err:
<statement>
except (RuntimeError, TypeError, NameError):
<statement>
else:
<statement>
finally:
<statement>
2
3
4
5
6
7
8
9
10
11
12
13
首先执行 try
和 except
之间的语句,如果未出现异常,则 try
语句执行结束。否则,会逐个匹配 except
语句,匹配上则执行 except
语句,否则会继续抛出异常。except Except as err
,我们可以通过 err
来访问异常对象,我们可以通过 err.args
来访问构造这个异常对象时的参数。
else
语句在 try
中执行完,且没有出现异常的时候执行。finally
语句指定了在 try
返回之前要做的事情,不管是否有异常发生,通常会被用来做一些收尾工作,比如关闭文件等。如果 finally
语句中指定了 return
语句,那么 finally
中 return
的会替换掉 try
中 return
的值。
抛出异常
我们可以通过 raise
语句抛出一个异常。
>>> try:
... raise NameError('HiThere')
... except NameError as err:
... print('An exception flew by!' + str(err.args))
... raise
...
An exception flew by! ('HiThere',)
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
NameError: HiThere
2
3
4
5
6
7
8
9
10
raise
语句还支持后跟一个 from
语句来实现异常的级联。
>>> def func():
... raise IOError
...
>>> try:
... func()
... except IOError as exc:
... raise RuntimeError('Failed to open database') from exc
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
File "<stdin>", line 2, in func
OSError
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
RuntimeError: Failed to open database
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
通过异常级联,我们可以清楚的看出异常抛出的链路。
注意,在 except
语句和 finally
语句中抛出的异常是自动级联的。
>>> try:
... raise NameError('aa')
... except NameError as err:
... raise RuntimeError from err
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
NameError: aa
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
RuntimeError
2
3
4
5
6
7
8
9
10
11
12
13
14
前面说到,finally
语句可以用来处理异常发生后的收尾工作。但是很多时候会显得比较繁琐,比如读写文件的时候,如果忘记在 finally
语句中关闭文件,则会导致内存泄漏等严重问题。
我们可以通过 with
语句来帮助我们自动处理这些收尾工作,使得代码更加简洁。
with open("myfile.txt") as f:
for line in f:
print(line, end="")
2
3
当然,with
语句不是所有地方都能用。要使用 with
语句,需实现 __enter__
和 __exit__
方法,具体细节可以看这里open in new window。
关注微信公众号,获取最新推送~
加微信,深入交流~