python学习笔记06-python错误、调试和测试

1.错误处理

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import logging
#定义一个自定义错误,继承自StandardError
class FooError(StandardError):
        pass
def func1(value):
        return 10/int(value)
def func2(value):
        #使用try-except-else捕获异常,打印异常日志,并且使用raise抛出一个FooError异常
        try:
                return func1(value)
        except ZeroDivisionError,e:
                logging.exception(e)
                raise FooError('invalid value: %s' % value)
        else:
                print 'func2 success'
def func3(value):
        #使用try-except-else-finally捕获并处理异常
        try:
                print '----START----'
                return func2(value)
        except FooError,e:
                print 'catch a fooerror'
        else:
                print 'func3 success'
        finally:
                print '----END----'

func3(0) ```

2.调试

1.print

2.断言assert

如果断言失败,assert语句本身就会抛出AssertionError:
assert的意思是,表达式n != 0应该是True,否则,后面的代码就会出错。 

# err.py
def foo(s):
    n = int(s)
    assert n != 0, 'n is zero!'
    return 10 / n
def main():
    foo('0')

启动Python解释器时可以用-O参数来关闭assert 

$ python -O err.py

关闭后,你可以把所有的assert语句当成pass来看 

3.logging

logging允许你指定记录信息的级别,有debug,info,warning,error等几个级别,当我们指定level=INFO时,logging.debug就不起作用了
logging的另一个好处是通过简单的配置,一条语句可以同时输出到不同的地方,比如console和文件 

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import logging
#设置logging的显示级别
logging.basicConfig(level=logging.INFO)
s = '0'
n = int(s)
logging.info('n = %d' % n)
print 10 / n

4.pdb单步调试

启动pdb单步调试 

$ python -m pdb err.py

命令l可以查看代码
命令n可以单步执行代码
命令p 变量名可以查看变量
命令q可以结束调试,退出程序 

5.pdb.set_trace()设置断点

在可能出错的地方放一个pdb.set_trace(),就可以设置一个断点 

# err.py
import pdb
s = '0'
n = int(s)
pdb.set_trace() # 运行到这里会自动暂停
print 10 / n

程序会自动在pdb.set_trace()暂停并进入pdb调试环境,可以用命令p查看变量,或者用命令c继续运行 

3.单元测试

mydict.py 

class Dict(dict):
    def __init__(self, **kw):
        super(Dict, self).__init__(**kw)
    def __getattr__(self, key):
        try:
            return self[key]
        except KeyError:
            raise AttributeError(r"'Dict' object has no attribute '%s'" % key)
    def __setattr__(self, key, value):
        self[key] = value

mydict_test.py 

import unittest
from mydict import Dict
class TestDict(unittest.TestCase):
    def test_init(self):
        d = Dict(a=1, b='test')
        self.assertEquals(d.a, 1)
        self.assertEquals(d.b, 'test')
        self.assertTrue(isinstance(d, dict))
    def test_key(self):
        d = Dict()
        d['key'] = 'value'
        self.assertEquals(d.key, 'value')
    def test_attr(self):
        d = Dict()
        d.key = 'value'
        self.assertTrue('key' in d)
        self.assertEquals(d['key'], 'value')
    def test_keyerror(self):
        d = Dict()
        with self.assertRaises(KeyError):
            value = d['empty']
    def test_attrerror(self):
        d = Dict()
        with self.assertRaises(AttributeError):
            value = d.empty
if __name__ == '__main__':
    unittest.main()

运行单元测试
方法一: 

$ python mydict_test.py

方法二: 

$ python -m unittest mydict_test

setUp与tearDown
这两个方法会分别在每调用一个测试方法的前后分别被执行
比如,可以在setUp()方法中连接数据库,在tearDown()方法中关闭数据库 

4.文档测试

Python内置的“文档测试”(doctest)模块可以直接提取注释中的代码并执行测试 

class Dict(dict):
    '''
    Simple dict but also support access as x.y style.
    >>> d1 = Dict()
    >>> d1['x'] = 100
    >>> d1.x
    100
    >>> d1.y = 200
    >>> d1['y']
    200
    >>> d2 = Dict(a=1, b=2, c='3')
    >>> d2.c
    '3'
    >>> d2['empty']
    Traceback (most recent call last):
        ...
    KeyError: 'empty'
    >>> d2.empty
    Traceback (most recent call last):
        ...
    AttributeError: 'Dict' object has no attribute 'empty'
    '''
    def __init__(self, **kw):
        super(Dict, self).__init__(**kw)
    def __getattr__(self, key):
        try:
            return self[key]
        except KeyError:
            raise AttributeError(r"'Dict' object has no attribute '%s'" % key)
    def __setattr__(self, key, value):
        self[key] = value
if __name__=='__main__':
    import doctest
    doctest.testmod()

注意到最后两行代码。当模块正常导入时,doctest不会被执行。只有在命令行运行时,才执行doctest。所以,不必担心doctest会在非测试环境下执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值