错误:
1、语法错误:代码不符合解释器或者编译器语法
2、逻辑错误:不完整、不合法输入、计算出现问题
异常:执行过程中出现问题导致程序无法执行
1、程序遇到逻辑或者算法问题
2、运行过程中计算机错误(内存不够或者IO错误)
区别:
错误:
代码运行前的语法或者逻辑错误
语法错误在执行前修改,逻辑错误无法修改
异常分为两个步骤
1、异常产生,检查到错误且解释器认为是异常,抛出异常
2、异常处理,截获异常,忽略或者终止程序处理异常;
错误
描述 | |
NameError | 尝试访问一个没有申明的变量 |
ZeroDivisionError | 除数为0 |
SyntaxError | 语法错误 |
IndexError | 索引超出序列范围 |
KeyError | 请求一个不存在的字典关键字 |
IOError | 输入输出错误(比如你要读的文件不存在) |
AttributeError | 尝试访问未知的对象属性 |
ValueError | 传给函数的参数类型不正确,比如给int()函数传入字符串形 |
Python完整的捕获异常的语句有点像:
try:
try_suite
except Exception1,Exception2,...,Argument:
exception_suite
...... #如果要处理多个异常,再写except Exception1,Exception2,...,Argument:
else:
no_exceptions_detected_suite
finally:
always_execute_suite
try:
try_suite
except Exception [e]:
exception block
注意:
except子句后面那个Argument其实是一个异常类的实例,包含了来自异常代码的诊断信息。也就是说,如果你捕获了一个异常,你就可以通过这个异常类的实例来获取更多的关于这个异常的信息。例如:
>>> try:
... 1/0
... except ZeroDivisionError,reason:
... pass
...
>>> type(reason)
>>> print reason
integer division or modulo by zero
>>> reason
ZeroDivisionError('integer division or modulo by zero',)
>>> reason.__class__
>>> reason.__class__.__doc__
'Second argument to a division or modulo operation was zero.'
>>> reason.__class__.__name__
'ZeroDivisionError'
面试期间可能会问的问题,下面两个实例能获取异常吗?
try:
undef
except:
print "catch an except"
这个是可以捕获异常的,
因为是运行时错误。
try:
if undef
except:
print "catch an except"
上面这个是不能捕获异常的,
因为是语法错误,
运行前错误
现在我们来说说这个else语句。Python中有很多特殊的else用法,比如用于条件和循环。放到try语句中,其作用其实也差不多:就是当没有检测到异常的时候,则执行else语句。举个例子大家可能更明白些:
try:
f = open('1.txt')
line = f.read(2)
num = int(line)
except IOError, e:
print "catch IOError: " , e
except ValueError, e:
print "catch ValueError:" , e
else:
print "No Error"
finally子句是无论是否检测到异常,都会执行的一段代码。我们可以丢掉except子句和else子句,单独使用try...finally,也可以配合except等使用。
try:
f = open('/home/changwen/1.txt')
print int(f.read())
finally:
print "file close"
f.close()
如果1.txt文件内容为“test"
file close Traceback (most recent call last): File "test2.py", line 3, in print int(f.read()) ValueError: invalid literal for int() with base 10: 'test\n' |
with context_expr [as var]:
with_suite
1.with语句用来代替try-except-finally语句,使代码更加简洁
with open('/home/changwen/1.txt') as f:
for line in f:
print line
上面这几行代码干了什么?
注意,with ... as 只能确保文件最后会关闭,但如果里面有异常,还是需要对其其捕获
使用with语句来使用这些共享资源,我们不用担心会因为某种原因而没有释放他。但并不是所有的对象都可以使用with语句,只有支持上下文管理协议(context management protocol)的对象才可以,那哪些对象支持该协议呢?如下表:file、decimal.Context、thread.LockType、threading.Lock、threading.RLock、threading.Condition、threading.Semaphore、threading.BoundedSemaphore
with语句实质是上下文管理:
1.上下文管理协议:包含方法__enter__() 和__exit__(),支持该协议的对象要实现这两个方法
2.上下文管理器:定义执行with语句时要建立的运行时上下文,负责执行with语句块上下文中的进入与退出操作
3.进入上下文管理器:调用管理器__enter__方法,如果设置as var语句, var变量接受__enter__()方法返回值
4.退出上下文管理器:调用管理器__exit__方法,
raise语句用于主动抛出异常
语法格式:raise[exception[, args]]
exception : 异常类
args : 描述异常信息的元组
raise TypeError, " test error"
Traceback (most recent call last): File " TypeError: test error |
assert 7==6, "test assert"
Traceback (most recent call last): File " AssertionError: test assert |
自定义异常:
1.python允许自定义异常用于描述python中没有涉及的异常情况;
2.自定义异常必须继承Exception类
3.自定义异常只能主动触发
#自定义异常类
class FileError(IOError):
pass
可以用try ... except捕获异常
>>> try:
... raise FileError, "test fileError"
... except FileError, e:
... print e
...
test fileError
再来一个自定义异常例子
#!/usr/bin/python2.7
class CustomError(Exception):
def __init__(self, info):
Exception.__init__(self)
self.errorinfo = info
print id(self)
def __str__(self):
return "CustionError: %s" % self.errorinfo
try:
raise CustomError("test CustomError")
except CustomError, e:
print "ErrorInfo: %d, %s" %(id(e), e)
changwen@ubuntu:~$ python test2.py
140242667936816 ErrorInfo: 140242667936816, CustionError: test CustomError |