Article directory
1. Error handling
try:
# 可能有异常的代码块
r = 10/int('2')
except ValueError as e:
# 有异常时执行,捕获指定类型及其子类型的错误
print('ValueError', e)
except ZeroDivisionError as e:
# 当前面的异常命中后,后面不会再次捕获
print('ZeroDivisionError', e)
else:
# 无异常时执行
print('no error.')
finally:
# 上面结束后一定会执行
print('finally')
call stack
From top to bottom, the entire wrong calling function chain, in order from outside to inside;
log error
try:
r = 10/int('0')
except Exception as e:
# 记录错误堆栈
logging.exception(e)
Throw an exception
# 自定义异常
class FooError(ValueError):
pass
# 抛出异常
raise FooError('invalid value')
# 捕获异常,原样抛出
except ValueError as e:
raise
# 转化成另一种异常抛出
except ZeroDivisionError:
raise ValueError('input error.')
When the program actively throws an exception, the possible exception and its cause should be clearly written in the document, so that the caller can handle the corresponding error;
2. debug
assert
If the asserted statement is not true, the assert statement will throw AssertionError;
assert n!=0, 'n is zero.'
The assertion can be turned off by -O
the parameter . After it is turned off, assert
the statement is equivalent to pass
;
logging
import logging
logging.basicConfig(level=logging.INFO)
logging.info('xxx')
logging level
- CRITICAL
- ERROR
- WARNING - root logger level default level
- INFO
- DEBUG
- NOTSET - default level, handles all messages
Another benefit of logging is that through configuration, a message can be output to different places at the same time, for example console
, files, database
;
use morelogging
pdb
-m pdb
Start with parameters .py
and run in a single step;
python -m pdb xxx.py
pdb
interface command
instruction | effect |
---|---|
l | view code |
n | single step |
p | p 变量名 view variables |
q | End debugging, exit the program |
c | keep running |
set_trace()
Set a breakpoint, and after entering debugging, c
run the command to automatically pause at the breakpoint;
IDE
3. unittest
TDD
Test Driven Development;
Unit testing is the guarantee for refactoring code in the future;
Unit tests should cover common input combinations, boundary conditions, and exceptions;
Unit testing should not be too complicated, otherwise it may have bugs;
write
import unittest
class TestDict(unittest.TestCase):
def test_init(self):
d = dict(a=1, b='test')
# 断言相等
self.assertEqual(d.a, 1)
self.assertEqual(d.b, 'test')
# 断言为真
self.assertTrue(isinstance(d, dict))
def test_keyerror(self):
d = dict()
# 期待语句块中抛出指定类型的 Error
with self.assertRaises(KeyError):
value = d['empty']
单元测试类
inherited from unittest.TestCase
;
单元测试方法
It must be test
named at the beginning, otherwise it will not be executed;
run
run by code
if __name__ == '__main__':
unittest.main()
Run with command arguments
python -m unittest mytest
setUp and tearDown
Executed before and after each call to a unit test;
4.doctest
Documentation tests, which can be used to run tests as well as sample code;
Strictly follow the input and output of the Python interactive command line to judge the correctness of the test results;
When testing exceptions, you can use ...
the output that represents the middle omission;
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(f"'Dict' object has no attribute '{
key}'")
def __setattr__(self, key, value):
self[key] = value
if __name__ == "__main__":
import doctest
doctest.testmod()
run
python mydict.py
If there is no output, it is running correctly;
- Previous: "Python Basics" Object-Oriented Programming
- Next: "Python Basics" I/O Programming, Regular Expressions
PS: Thank you to everyone who has the same goals for reading, welcome to pay attention, comment, and praise!