更多课程 选择中心


Python培训

400-996-5531

Python错误、调试和测试


1.错误处理

Python内置了 try...except...finally...的错误处理机制。

如果认为代码可能出错,用try运行代码;如果代码执行出错,直接跳转到except语句,except语句可以有多个;如果没有错误,会执行else语句;如果有finally,则最后执行finally语句。如:

	
	
	
	
	
	
  1. try:

  2.    print('try...')

  3.    r = 10 / 0

  4.    print('result:', r)

  5. except ValueError as e:

  6.    print('ValueError:', e)

  7. except ZeroDivisionError as e:

  8.    print('except:', e)

  9. else:

  10.    print('no error!')

  11. finally:

  12.    print('finally...')

  13. print('END')

错误信息是一个调用栈,可以跟踪错误信息。

2.logging打印

Python内置的logging模块可以容易的记录错误信息。

	
	
	
	
	
	
  1. import logging

  2. def main():

  3.    try:

  4.        bar('0')

  5.    except Exception as e:

  6.        logging.exception(e)

3.raise抛出错误

可以自己定义错误类型,然后通过 raise语句抛出错误的实例。

	
	
	
	
	
	
  1. class FooError(ValueError):

  2.    pass

  3. def foo(s):

  4.    n = int(s)

  5.    if n==0:

  6.        raise FooError('invalid value: %s' % s)

  7.    return 10 / n

  8. foo('0')

4.调试

简单的办法是通过print()打印错误信息,还有一种是使用断言(assert)。凡是可以用print的地方都可以都可以使用断言。

	
	
	
	
	
	
  1. def foo(s):

  2.    n = int(s)

  3.    assert n != 0, 'n is zero!'

  4.    return 10 / n

  5. def main():

  6.    foo('0')

启动Python解释器时可以用-O(字母O)参数来关闭assert:

	
	
	
	
	
	
  1. $ python -O err.py

前面说的logging其实可以更加强力,它允许指定记录信息的级别。信息有debug,info,warning,error等几个级别。比如:

	
	
	
	
	
	
  1. import logging

  2. logging.basicConfig(level=logging.INFO)

当指定level为info时,debug就不起作用了;指定为warning时,debug和info就不起作用了。

pdb是另一种调试方法,它是Python的调试器,让程序以单步的方式运行。当然通过IDE进行单步调试是最好的。

5.单元测试

通过使用Python自带的unittest模块,可以进行单元测试。编写一个类继承unittest.TestCase。

	
	
	
	
	
	
  1. class Dict(dict):

  2.    def __init__(self, **kw):

  3.        super().__init__(**kw)

  4.    def __getattr__(self, key):

  5.        try:

  6.            return self[key]

  7.        except KeyError:

  8.            raise AttributeError(r"'Dict' object has no attribute '%s'" % key)

  9.    def __setattr__(self, key, value):

  10.        self[key] = value

上面的Dict类的单元测试可以写为:

	
	
	
	
	
	
  1. import unittest

  2. from mydict import Dict

  3. class TestDict(unittest.TestCase):

  4.    def test_init(self):

  5.        d = Dict(a=1, b='test')

  6.        self.assertEqual(d.a, 1)

  7.        self.assertEqual(d.b, 'test')

  8.        self.assertTrue(isinstance(d, dict))

  9.    def test_key(self):

  10.        d = Dict()

  11.        d['key'] = 'value'

  12.        self.assertEqual(d.key, 'value')

  13.    def test_attr(self):

  14.        d = Dict()

  15.        d.key = 'value'

  16.        self.assertTrue('key' in d)

  17.        self.assertEqual(d['key'], 'value')

  18.    def test_keyerror(self):

  19.        d = Dict()

  20.        with self.assertRaises(KeyError):

  21.            value = d['empty']

  22.    def test_attrerror(self):

  23.        d = Dict()

  24.        with self.assertRaises(AttributeError):

  25.            value = d.empty

以test开头的方法就是测试方法,不以test开头的方法不被认为是测试方法,测试的时候不会被执行。对每一类测试都需要编写一个test_xxx()方法。

单元测试中提供了很多内置的条件判断。通过调用这些方法就可以断言输出是否是期望的。

单元测试的运行可以在后面加上:

	
	
	
	
	
	
  1. if __name__ == '__main__':

  2.    unittest.main()

将Python作为一个正常的脚本运行。或者通过命令行参数运行。

	
	
	
	
	
	
  1. $ python -m unittest mydict_test

当然用直接用IDE也是可以的。

单元测试有两个特殊的方法, setUp()tearDown()方法,这两个方法会分别在每调用一个测试方法的前后分别被执行。

setUp()和tearDown()方法有什么用呢?设想你的测试需要启动一个数据库,这时,就可以在setUp()方法中连接数据库,在tearDown()方法中关闭数据库,这样,不必在每个测试方法中重复相同的代码。

6.文档测试

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

doctest严格按照Python交互式命令行的输入和输出来判断测试结果是否正确。只有测试异常的时候,可以用...表示中间一大段的输出。

	
	
	
	
	
	
  1. class Dict(dict):

  2.    '''

  3.    Simple dict but also support access as x.y style.

  4.    >>> d1 = Dict()

  5.    >>> d1['x'] = 100

  6.    >>> d1.x

  7.    100

  8.    >>> d1.y = 200

  9.    >>> d1['y']

  10.    200

  11.    >>> d2 = Dict(a=1, b=2, c='3')

  12.    >>> d2.c

  13.    '3'

  14.    >>> d2['empty']

  15.    Traceback (most recent call last):

  16.        ...

  17.    KeyError: 'empty'

  18.    >>> d2.empty

  19.    Traceback (most recent call last):

  20.        ...

  21.    AttributeError: 'Dict' object has no attribute 'empty'

  22.    '''

  23.    def __init__(self, **kw):

  24.        super(Dict, self).__init__(**kw)

  25.    def __getattr__(self, key):

  26.        try:

  27.            return self[key]

  28.        except KeyError:

  29.            raise AttributeError(r"'Dict' object has no attribute '%s'" % key)

  30.    def __setattr__(self, key, value):

  31.        self[key] = value

  32. if __name__=='__main__':

  33.    import doctest

  34.    doctest.testmod()

运行时什么输出都没有,这时正常的。但是如果代码有错误,比如没有getattr方法,文档测试就会出错。

看最后两行代码,当模块正常导入时,doctest不会被执行。只有在命令行直接运行时,才执行doctest。

预约申请免费试听课

填写下面表单即可预约申请免费试听! 怕学不会?助教全程陪读,随时解惑!担心就业?一地学习,可全国推荐就业!

上一篇:Python数据科学学习书籍书单推荐
下一篇:Python爬虫:该如何学习数据爬虫

2021年Python全套免费视频教程在哪里?

Python编程学习路线

Python最高有几级?

人工智能与语音遥控的区别?

Copyright © 2023 Tedu.cn All Rights Reserved 京ICP备08000853号-56 京公网安备 11010802029508号 达内时代科技集团有限公司 版权所有

选择城市和中心
黑龙江省

吉林省

河北省

湖南省

贵州省

云南省

广西省

海南省