Python的异常处理
常见错误
1.ZeroDivisionError(零除错误)
In [1]: 10/0
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
<ipython-input-1-242277fd9e32> in <module>()
----> 1 10/0
ZeroDivisionError: integer division or modulo by zero
2.IOError(文件错误)
In [2]: open('hello')
---------------------------------------------------------------------------
IOError Traceback (most recent call last)
<ipython-input-2-9834044a9e14> in <module>()
----> 1 open('hello')
IOError: [Errno 2] No such file or directory: 'hello'
3.SyntaxError(语法错误)
In [3]: for i in [1,2,3]
File "<ipython-input-3-ae71676907af>", line 1
for i in [1,2,3]
^
SyntaxError: invalid syntax
4.IndexError(索引错误)
In [4]: t = (1,2,3)
In [5]: t[3]
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-5-7d5cf04057c5> in <module>()
----> 1 t[3]
IndexError: tuple index out of range
5.KeyError(字典的key错误)
In [7]: d = {'name':'cici'}
In [8]: d['name']
Out[8]: 'cici'
In [9]: d['age']
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-9-39d5d5cefe61> in <module>()
----> 1 d['age']
KeyError: 'age'
6.NameError(名称错误)
In [10]: print a
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-10-9d7b17ad5387> in <module>()
----> 1 print a
NameError: name 'a' is not defined
错误排查
捕获异常
python异常处理机制: try….except…finally…
如果异常则执行except后的语句,没有异常则直接跳过,也可以用else来提示没有异常
finally后的语句是必然执行的,不管try后的语句是否正确
1.已知错误(跳过错误继续执行)
#!/usr/bin/env python
# coding:utf-8
_author_ = "lvah"
try: #用 try 来运行可能会出错的代码
print 'starting...'
li = [1, 2, 3]
print a
print li[3]
except IndexError: #用except来捕获错误,如果异常则执行
print 'index out of list'
except NameError,e: #捕获第二个错误,同时给错误赋值
print e
finally: #必执行的
print 'ending..'
2.未知错误
#!/usr/bin/env python
# coding:utf-8
_author_ = "lvah"
try:
print 'starting...'
li = [1, 2, 3]
print a
print li[3]
except BaseException,e: #BaseException是一个错误的父类,表示所有错误
print 'Error:%s'%e
else:
print 'no error'
finally:
print 'ending..'
3.没有异常的情况
#!/usr/bin/env python
# coding:utf-8
_author_ = "lvah"
try:
print 'starting...'
li = [1, 2, 3]
li.append(4)
a = 1
print a
print li[3]
except IndexError: #检测第一个错误
print 'index out of list'
except NameError: #检测第二个错误
print 'name is not defined'
else: #没有异常时
print 'no error'
finally:
print 'ending..'
4.函数排错
直接在主函数里排错,可以增强排错效率
#!/usr/bin/env python
# coding:utf-8
_author_ = "lvah"
def func1(s):
return func2(s) * 2
def func2(s):
return 20 / s
def main():
try:
print func1('10')
except BaseException, e:
print e
main()
5.错误日志
#!/usr/bin/env python
# coding:utf-8
_author_ = "lvah"
import logging ##导入日志模块
logging.basicConfig(filename='err.log') #日志文件的定义
def func1(s):
return func2(s) * 2
def func2(s):
return 20 / s
def main():
try:
print func1('10')
except Exception as e:
logging.exception(e) #所有错误导入到日志文件
main()
抛出异常
except: 捕获异常
raise: 抛出异常
#!/usr/bin/env python
# coding:utf-8
_author_ = "lvah"
class MyError(BaseException):
pass
a = 1
if a == 1:
raise MyError
#!/usr/bin/env python
# coding:utf-8
_author_ = "lvah"
class MyError(BaseException):
pass
def func1(s):
return func2(s) * 2
def func2(s):
return 20 / int(s)
def main():
try:
print func1('0')
except ZeroDivisionError as e:
raise MyError
#ZeroDivisionError 转换为 MyError
main()
调试
用 print 把可能有问题的变量打印出来
用 print 最大的坏处是将来还得删掉它,运行结果也会包含很多垃圾信息。
断言
凡是用 print 来辅助查看的地方,都可以用断言(assert)来替代:;
如果断言失败, assert 语句本身就会抛出 AssertionError
#!/usr/bin/env python
# coding:utf-8
_author_ = "lvah"
def foo(s):
n = int(s)
return 10 / n
def main():
foo('0')
assert foo(5) == 2
print 'right'
Python 解释器执行时可以用 -O 参数来关闭 assert,把所有的 assert 语句当成 pass。
[aaa@qq.com date7.15]$ python -O error_4.py
logging
logging 不会抛出错误,而且可以输出到文件
logging.info() 就可以输出一段文本到日志文件中
#!/usr/bin/env python
# coding:utf-8
_author_ = "lvah"
import logging
logging.basicConfig(filename='logging.log',level=logging.INFO)
def foo(s):
# 日志级别:debug,info,waring,error
n = int(s)
logging.info('n=%d'%n)
logging.warning('n=%d....warn'%n)
return 10 / n
def main():
foo('10')
main()
pdb
[aaa@qq.com date7.15]$ python -m pdb error_3.py
n – next
p 变量 – 取出变量
q – 退出
#!/usr/bin/env python
# coding:utf-8
_author_ = "lvah"
import pdb
n1 =1
n = int(n1)
print n
pdb.set_trace() #在可能出错的地方放一个 pdb.set_trace() ,就可以设置一个断点
print 'hello'
pdb.set_trace()
s = 2
print s
python …
程序会自动在 pdb.set_trace() 暂停并进入 pdb 调试环境, p 查看变量, c 继续运行