• 中文
    • English
  • 注册
  • 查看作者
  • 第十六章:错误、调试和测试

    一. 错误处理

    python使用于try 、except、finally的错误捕获机制,如下图:

    try:
        print('try...')
        r = 10 / 0
        print('result:', r)
    except ZeroDivisionError as e:
        print('except:', e)
    finally:
        print('finally...')
    print('END')

    try中是可能出错的语句,except中对捕获的错误进行声明和处理,finally中的语句无论错误与否都会执行。

    另外,try…except捕获错误可以跨越多层调用,比如函数main()调用bar(),bar()调用foo(),结果foo()出错了,这时,只要main()捕获到了,就可以处理。

    Python内置的logging模块可以非常容易地记录错误信息:

    import logging
    
    def foo(s):
        return 10 / int(s)
    
    def bar(s):
        return foo(s) * 2
    
    def main():
        try:
            bar('0')
        except Exception as e:
            logging.exception(e)
    
    main()
    print('END')

    二. 调试

    调试除了在指定位置输出print语句后,还可以通过以下3种方式来替代:

    1. 断言(assert):

    def foo(n):
        assert n != 0, 'n is zero!' #False时执行
        return 10 / n
    
    
    if __name__ == '__main__':
        foo(1)

    2. logging:

    import logging
    logging.basicConfig(level=logging.error) # 通过定义日志等级,输出不同级别的信息
    
    def foo(n):
        logging.info('n = %d' % n)
        return 10 / n
    if __name__ == '__main__':
        foo(0)

    3. pdb

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

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

    可以用命令p查看变量

    三. 单元测试

    为了编写单元测试,我们需要引入Python自带的unittest模块

    import unittest
    
    class Test(unittest.TestCase):
        def test_a(self):
            #self.assertEqual(1,-1) #通过断言判断是否相等
           # with self.assertRaises(KeyError): # 当访问不存在当key时,抛出keyError
           #     value = d['empty']
           # with self.assertRaises(AttributeError): # 通过d.empty访问不存在的key时,抛出AttributeError:
           #     value = d.empty 
            print("tes开头,我就是测试方法")
    
        def setUp(self):
            print('每个测试方法执行前,我都会执行...')
    
        def tearDown(self):
            print('每个方法执行后,我都会执行...')

    四. 文档测试

    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()

    参考资料

    [1] 廖雪峰-Python教程

  • 0
  • 0
  • 0
  • 1.4k
  • 请登录之后再进行评论

    登录
    单栏布局 侧栏位置: