python错误与测试

    技术2022-07-13  66

    错误处理

    try、except、finally

    先执行try中的语句,如果发生了错误则被except捕获,否则无错误则执行else语句,最终执行finally语句

    try: print('try...') r = 10 / int('2') print('result:', r) except ValueError as e: print('ValueError:', e) except ZeroDivisionError as e: print('ZeroDivisionError:', e) else: print('no error!') finally: print('finally...') print('END') try... result: 5.0 no error! finally... END

    抛出异常

    Python中常见的异常 IOError: 输入/输出异常;(基本上是无法打开文件) ImportError: 无法导入模块或包;(出现这个异常基本上是路径问题或名称错误) IndentationError: 缩进错误;(代码没有正确对齐) NameError: 没有声明、或初始化对象 KeyError:试图访问字典里不存在的键 AttributeError:试图访问一个对象没有的属性 TypeError :类型不匹配 ValueError:传入一个调用者不期望的值,即使值的类型是正确的

    异常本身也是类

    class FooError(ValueError):#定义异常 pass def foo(s): n = int(s) if n==0: raise FooError('无效的值: %s' % s)#抛出异常 return 10 / n foo('0') --------------------------------------------------------------------------- FooError Traceback (most recent call last) <ipython-input-10-0c3ece3b8a4a> in <module> 8 return 10 / n 9 ---> 10 foo('0') <ipython-input-10-0c3ece3b8a4a> in foo(s) 5 n = int(s) 6 if n==0: ----> 7 raise FooError('无效的值: %s' % s)#抛出异常 8 return 10 / n 9 FooError: 无效的值: 0

    直接使用rasie,不带任何内容是直接抛出错误

    def foo(s): n = int(s) if n==0: raise ValueError('invalid value: %s' % s) return 10 / n def bar(): try: foo('0') except ValueError as e: print('ValueError!') raise #继续抛出当前错误 bar() ValueError! --------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-11-2304461f3f2b> in <module> 12 raise #继续抛出当前错误 13 ---> 14 bar() <ipython-input-11-2304461f3f2b> in bar() 7 def bar(): 8 try: ----> 9 foo('0') 10 except ValueError as e: 11 print('ValueError!') <ipython-input-11-2304461f3f2b> in foo(s) 2 n = int(s) 3 if n==0: ----> 4 raise ValueError('invalid value: %s' % s) 5 return 10 / n 6 ValueError: invalid value: 0

    assert断言

    assert 条件 , 抛出AssertionError异常携带的信息

    eg:assert n!=0,'n is zero!'

    在运行python文件的时候可以关闭断言开关python -O xxx.py,此处为大写字母O,不是数字0

    def foo(s): n = int(s) assert n != 0, 'n is zero!' return 10 / n foo('0') --------------------------------------------------------------------------- AssertionError Traceback (most recent call last) <ipython-input-24-1d060d98ffe3> in <module> 4 return 10 / n 5 ----> 6 foo('0') <ipython-input-24-1d060d98ffe3> in foo(s) 1 def foo(s): 2 n = int(s) ----> 3 assert n != 0, 'n is zero!' 4 return 10 / n 5 AssertionError: n is zero!

    logging模块

    在运行文件的时候才会有效果 交互模式下不显示

    import logging# 导入logging的包 logging.basicConfig(level=logging.INFO)#日志输出级别设置为info logging.info('123456')#输出 INFO:root:n = 0 Traceback (most recent call last): File "test.py", line 7, in <module> print(10 / n) ZeroDivisionError: division by zero

    单元测试

    先写一个用于被测试的类

    class Dict(dict): def __init__(self, **kw): super().__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 # 它的使用方法如下 d = Dict(a=1, b=2) print(d['a']) print(d.b) 1 2

    编写单元测试类

    import unittest #导入单元测试模块 class TestDict(unittest.TestCase):#编写单元测试类,继承unittest.TestCase #编写单元测试方法 必须以test开头 def test_init(self): d = Dict(a=1, b='test') self.assertEqual(d.a, 1)#unittest.TestCase自带的断言方法 self.assertEqual(d.b, 'test') self.assertTrue(isinstance(d, dict)) def test_key(self): d = Dict() d['key'] = 'value' self.assertEqual(d.key, 'value') def test_attr(self): d = Dict() d.key = 'value' self.assertTrue('key' in d) self.assertEqual(d['key'], 'value') def test_keyerror(self): d = Dict() with self.assertRaises(KeyError):#unittest.TestCase期待抛出错误KeyError value = d['empty'] def test_attrerror(self): d = Dict() with self.assertRaises(AttributeError):#unittest.TestCase期待抛出错误AttributeError value = d.empty

    运行单元测试

    方法1

    直接在代码中加入

    if __name__ == '__main__': unittest.main()

    然后直接运行该文件 python xxx.py

    方法2

    在命令行输入python -m unittest xxx,其中xxx为不带后缀名py的文件名

    单元测试中的两个特殊方法setUp与tearDown

    分别在每个测试方法前后执行

    比如测试方法需要连接数据库,可以在setUp方法中打开数据库连接,在tearDown方法中关闭数据库的连接

    class TestDict1(unittest.TestCase): def setUp(self): print('setUp...') def tearDown(self): print('tearDown...')
    Processed: 0.011, SQL: 9