22
33#错误和异常(1)
44
5- 虽然在前面的学习中,已经遇到了错误和异常问题,但是一直没有很认真的研究它。现在来近距离观察错误和异常 。
5+ 对于程序在执行过程中因为错误或者别的原因而中止的现象,已经看过多次了,那些都可以归为“错误和异常”现象。本章就要对这种现象进行近距离观察 。
66
77##错误
88
9- python中的错误之一是语法错误(syntax errors),比如:
9+ 不管是小白还是高手,在编写程序的时候,错误往往是难以避免的。可能是因为语法用错了,也可能是拼写做了,当然还可能其它莫名其妙的错误,比如冒号写成了全角的了,等等。总之,编程中有相当一部分工作就是要不停地修改错误。
10+
11+ Python中的错误之一是语法错误(syntax errors),比如:
1012
1113 >>> for i in range(10)
1214 File "<stdin>", line 1
1315 for i in range(10)
1416 ^
1517 SyntaxError: invalid syntax
1618
17- 上面那句话因为缺少冒号` : ` ,导致解释器无法解释,于是报错。这个报错行为是由python的语法分析器完成的 ,并且检测到了错误所在文件和行号(` File "<stdin>", line 1 ` ),还以向上箭头` ^ ` 标识错误位置(后面缺少` : ` ),最后显示错误类型。
19+ 上面那句话因为缺少冒号` : ` ,导致解释器无法解释,于是报错。这个报错行为是由Python的语法分析器完成的 ,并且检测到了错误所在文件和行号(` File "<stdin>", line 1 ` ),还以向上箭头` ^ ` 标识错误位置(后面缺少` : ` ),最后显示错误类型。
1820
19- 错误之二是在没有语法错误之后,会出现逻辑错误。逻辑错误可能会由于不完整或者不合法的输入导致 ,也可能是无法生成、计算等,或者是其它逻辑问题。
21+ 另一种常见错误是逻辑错误。逻辑错误可能是由于不完整或者不合法的输入导致 ,也可能是无法生成、计算等,或者是其它逻辑问题。
2022
21- 当python检测到一个错误时 ,解释器就无法继续执行下去,于是抛出异常 。
23+ 当Python检测到一个错误时 ,解释器就无法继续执行下去,于是抛出提示信息,即为异常 。
2224
2325##异常
2426
@@ -27,12 +29,16 @@ python中的错误之一是语法错误(syntax errors),比如:
2729 >>> 1/0
2830 Traceback (most recent call last):
2931 File "<stdin>", line 1, in <module>
30- ZeroDivisionError: integer division or modulo by zero
32+ ZeroDivisionError: integer division or modulo by zero #Python 3: ZeroDivisionError: division by zero
3133
32- 当python抛出异常的时候 ,首先有“跟踪记录(Traceback)”,还可以给它取一个更优雅的名字“回溯”。后面显示异常的详细信息。异常所在位置(文件、行、在某个模块)。
34+ 当Python抛出异常的时候 ,首先有“跟踪记录(Traceback)”,还可以给它取一个更优雅的名字“回溯”。后面显示异常的详细信息。异常所在位置(文件、行、在某个模块)。
3335
3436最后一行是错误类型以及导致异常的原因。
3537
38+ 在刚才的例子中,明确告诉我们一场的类型是` ZeroDivisionError ` ,并且对此异常类型做了解释(虽然Python 2和Python 3的解释不完全一致,但意思是一样的)。
39+
40+ > 为什么0不能作除数(分母)?虽然小学生都知道不能作,但是不一定知道为什么不能作。读者对此有兴趣思考思考吗?
41+
3642下表中列出常见的异常
3743
3844| 异常 | 描述|
@@ -54,7 +60,7 @@ python中的错误之一是语法错误(syntax errors),比如:
5460 File "<stdin>", line 1, in <module>
5561 NameError: name 'bar' is not defined
5662
57- python中变量需要初始化,即要赋值。虽然不需要像某些语言那样声明,但是要赋值先。 因为变量相当于一个标签,要把它贴到对象上才有意义。
63+ Python中变量虽然不需在使用变量之前先声明类型,但也需要对变量进行赋值,然后才能使用。不被赋值的变量,不能再Python中存在, 因为变量相当于一个标签,要把它贴到对象上才有意义。
5864
5965###ZeroDivisionError
6066
@@ -63,7 +69,7 @@ python中变量需要初始化,即要赋值。虽然不需要像某些语言
6369 File "<stdin>", line 1, in <module>
6470 ZeroDivisionError: integer division or modulo by zero
6571
66- 貌似这样简单的错误时不会出现的 ,但在实际情境中,可能没有这么容易识别,所以,依然要小心为妙。
72+ 你或许已经有足够的信心,貌似这样简单的错误在你的程序中是不会出现的 ,但在实际情境中,可能没有这么容易识别,所以,依然要小心为妙。
6773
6874###SyntaxError
6975
@@ -73,9 +79,9 @@ python中变量需要初始化,即要赋值。虽然不需要像某些语言
7379 ^
7480 SyntaxError: invalid syntax
7581
76- 这种错误发生在python代码编译的时候 ,当编译到这一句时,解释器不能讲代码转化为python字节码 ,就报错。只有改正才能继续。所以,它是在程序运行之前就会出现的(如果有错) 。现在有不少编辑器都有语法校验功能,在你写代码的时候就能显示出语法的正误,这多少会对编程者有帮助。
82+ 这种错误发生在Python代码编译的时候 ,当编译到这一句时,解释器不能讲代码转化为Python字节码 ,就报错。它只在程序运行之前出现 。现在有不少编辑器都有语法校验功能,在你写代码的时候就能显示出语法的正误,这多少会对编程者有帮助。
7783
78- ###IndexError
84+ ###IndexError和KeyError
7985
8086 >>> a = [1,2,3]
8187 >>> a[4]
@@ -98,11 +104,11 @@ python中变量需要初始化,即要赋值。虽然不需要像某些语言
98104 File "<stdin>", line 1, in <module>
99105 IOError: [Errno 2] No such file or directory: 'foo'
100106
101- 如果你确认有文件,就一定要把路径写正确,因为你并没有告诉python对你的computer进行全身搜索, 所以,python会按照你指定位置去找 ,找不到就异常。
107+ 如果你确认有文件,就一定要把路径写正确,因为你并没有告诉Python要对你的Computer进行全身搜查。 所以,Python会按照你指定位置去找 ,找不到就异常。
102108
103109###AttributeError
104110
105- >>> class A(object): pass
111+ >>> class A(object): pass #Python 3: class A: pass
106112 ...
107113 >>> a = A()
108114 >>> a.foo
@@ -112,18 +118,22 @@ python中变量需要初始化,即要赋值。虽然不需要像某些语言
112118
113119属性不存在。这种错误前面多次见到。
114120
115- 其实,python内建的异常也不仅仅上面几个 ,上面只是列出常见的异常中的几个。比如还有:
121+ Python内建的异常也不仅仅上面几个 ,上面只是列出常见的异常中的几个。比如还有:
116122
117123 >>> range("aaa")
118124 Traceback (most recent call last):
119125 File "<stdin>", line 1, in <module>
120126 TypeError: range() integer end argument expected, got str.
121-
127+ #Python 3:
128+ #TypeError: 'str' object cannot be interpreted as an integer
129+
122130总之,如果读者在调试程序的时候遇到了异常,不要慌张,这是好事情,是python在帮助你修改错误。只要认真阅读异常信息,再用` dir() ` ,` help() ` 或者官方网站文档、google等来协助,一定能解决问题。
123131
124132##处理异常
125133
126- 在一段程序中,为了能够让程序健壮,必须要处理异常。举例:
134+ 如果在程序运行过程中,出现了“抛出异常”的现象,程序就会中止运行。这样的程序是不“健壮”的,“健壮”的程序应该是不为各种“异常”所击倒,所以,要在程序里面对各种异常进行处理。
135+
136+ Python 2:
127137
128138 #!/usr/bin/env python
129139 # coding=utf-8
@@ -142,6 +152,25 @@ python中变量需要初始化,即要赋值。虽然不需要像某些语言
142152 print "*************************"
143153 else:
144154 break
155+ Python 3:
156+
157+ #!/usr/bin/env python
158+ # coding=utf-8
159+
160+ while 1:
161+ print("this is a division program.")
162+ c = input("input 'c' continue, otherwise logout:")
163+ if c == 'c':
164+ a = input("first number:")
165+ b = input("second number:")
166+ try:
167+ print(float(a)/float(b))
168+ print("*************************")
169+ except ZeroDivisionError:
170+ print("The second number can't be zero!")
171+ print("*************************")
172+ else:
173+ break
145174
146175运行这段程序,显示如下过程:
147176
@@ -162,15 +191,15 @@ python中变量需要初始化,即要赋值。虽然不需要像某些语言
162191 input 'c' continue, otherwise logout:d
163192 $
164193
165- 从运行情况看,当在第二个数,即除数为0时,程序并没有因为这个错误而停止,而是给用户一个友好的提示,让用户有机会改正错误。这完全得益于程序中“处理异常”的设置,如果没有“处理异常”,异常出现,就会导致程序终止 。
194+ 从运行情况看,当在第二个数,即除数为0时,程序并没有因为这个错误而停止,而是给用户一个友好的提示,让用户有机会改正错误。这完全得益于程序中“处理异常”的设置,如果没有“处理异常”,当异常出现时就会导致程序中止 。
166195
167- 处理异常的方式之一,使用 ` try...except... ` 。
196+ ### ` try...except... ` 。
168197
169- 对于上述程序,只看try和except部分 ,如果没有异常发生,except子句在try语句执行之后被忽略;如果try子句中有异常可 ,该部分的其它语句被忽略,直接跳到except部分 ,执行其后面指定的异常类型及其子句。
198+ 对于上述程序,只看 ` try ` 和 ` except ` 部分 ,如果没有异常发生,` except ` 子句在 ` try ` 语句执行之后被忽略;如果 ` try ` 子句中有异常可 ,该部分的其它语句被忽略,直接跳到 ` except ` 部分 ,执行其后面指定的异常类型及其子句。
170199
171- except后面也可以没有任何异常类型 ,即无异常参数。如果这样,不论try部分发生什么异常,都会执行except 。
200+ ` except ` 后面也可以没有任何异常类型 ,即无异常参数。如果这样,不论 ` try ` 部分发生什么异常,都会执行 ` except ` 。
172201
173- 在except子句中 ,可以根据异常或者别的需要,进行更多的操作。比如:
202+ 在 ` except ` 子句中 ,可以根据异常或者别的需要,进行更多的操作。比如:
174203
175204 #!/usr/bin/env python
176205 # coding=utf-8
@@ -182,7 +211,7 @@ except后面也可以没有任何异常类型,即无异常参数。如果这
182211 return eval(express)
183212 except ZeroDivisionError:
184213 if self.is_raise:
185- print "zero can not be division."
214+ print "zero can not be division." #Python 3: "zero can not be division."
186215 else:
187216 raise
188217
@@ -203,13 +232,13 @@ except后面也可以没有任何异常类型,即无异常参数。如果这
203232 >>> eval("3+5")
204233 8
205234
206- 另外,在except子句中 ,有一个` raise ` ,作为单独一个语句。它的含义是将异常信息抛出。并且,except子句用了一个判断语句 ,根据不同的情况确定走不同分支。
235+ 另外,在 ` except ` 子句中 ,有一个` raise ` ,作为单独一个语句。它的含义是将异常信息抛出。并且,` except ` 子句用了一个判断语句 ,根据不同的情况确定走不同分支。
207236
208237 if __ name__ == "__ main__ ":
209238 c = Calculator()
210239 print c.calc("8/0")
211240
212- 这时候` is_raise = False ` ,则会:
241+ 故意出现0做分母的情况。 这时候` is_raise = False ` ,则会:
213242
214243 $ python 21602.py
215244 Traceback (most recent call last):
@@ -218,7 +247,7 @@ except后面也可以没有任何异常类型,即无异常参数。如果这
218247 File "21602.py", line 8, in calc
219248 return eval(express)
220249 File "<string>", line 1, in <module>
221- ZeroDivisionError: integer division or modulo by zero
250+ ZeroDivisionError: integer division or modulo by zero #Python 3的信息略有差异
222251
223252如果将` is_raise ` 的值改为True,就是这样了:
224253
0 commit comments