python中有两类错误:语法错误(syntax errors)和异常(exceptions)。
1、语法错误
语法错误是“真正的错误”,如果使用IDE的话(比如pyChrome),IDE中一般会有提示,即使没看到提示,运行时也会报SyntaxError错误,比如:
SyntaxError: unexpected EOF while parsing
2、异常
python中的异常体系没有Java中那么复杂(Java中分运行时异常和检查异常),python将没有语法错误、但是运行时监测到的错误称为“异常”。比如:
>>> 10 * (1/0)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ZeroDivisionError: int division or modulo by zero
>>> 4 + spam*3
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: name 'spam' is not defined
>>> '2' + 2
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: Can't convert 'int' object to str implicitly
ZeroDivisionError、NameError、TypeError都是Python中常见的异常。
2.1、异常处理
和Java中的异常处理机制(try…catch…finally)类似,python同样可以通过(try…except…finally)对异常进行处理。例如:
import sys
try:
f = open("myfile.txt")
s = f.readline()
i = int(s.strip())
# 可以用as为异常实例指定一个别名
except OSError as err:
print("OS error: {0}".format(err))
except ValueError:
print("Could not convert data to an integer.")
# 可以不指定异常,这样的话会捕捉所有异常
except :
print("Unexpected error:", sys.exc_info()[0])
pass
# 和java相同,在任何情况下,finally都会被执行
finally :
f.close()
由于和Java中的异常处理机制类似,这里只侧重于不同点:
- python中的except后可以跟一个else子句,当 try 语句没有抛出异常时,需要执行一些代码,可以使用这个子句。
for arg in sys.argv[1:]:
try:
f = open(arg, 'r')
except IOError:
print('cannot open', arg)
# 当没有捕获到IOError时调用
else:
print(arg, 'has', len(f.readlines()), 'lines')
f.close()
这样做的好处是可以防止“误捕获”异常。
- 和Java中相同,finally字句一般用于释放资源,并且如果出现了不在except范围内的异常,该异常会在finally执行完毕后抛出。不同之处在于,python提供了另一种释放资源的方式:使用with语句(注意并不是所有对象都适用)。with…as…修饰的对象在使用完毕后总会自动被清理。
with open("myfile.txt") as f:
for line in f:
print(line)
2.2、抛出异常
raise类似于java中的throw,用于主动抛出异常。例如:
# 抛出带参数的异常
raise NameError('haha')
raise后不跟参数,表示“向外继续抛出当前的异常”(相当于Java中的throws),例如:
try:
raise KeyboardInterrupt
except NameError:
print('a error, but I throw it outside')
raise
2.3、自定义异常
python中的异常都是Exception的派生类,可以通过继承Exception类来自定义异常。和Java中异常一般以Exception结尾不同,python中的异常一般以Error结尾,例如:
class MyError(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)
try:
raise MyError('a error')
except MyError as e:
print(e)