8、错误、调试和测试

错误处理 #

import logging  
try:
    print('try...')
    r = 10 / int('2')
    print('result:', r)
    # 抛出错误
    raise FooError('invalid value: %s' % s)
except ValueError as e:
    # 记录错误
    logging.exception(e)
    print('ValueError:', e)
except ZeroDivisionError as e:
    print('ZeroDivisionError:', e)
else:
    print('no error!')
finally:
    print('finally...')
print('END')

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`语句如果不带参数,就会把当前错误原样抛出
        raise

bar()

所有的错误类型都继承自BaseException,可以捕获所有子类错误。

except永远也捕获不到UnicodeError,因为UnicodeErrorValueError的子类

调试 #

# 1、 print 打印

# 2、断言assert
# `assert`的意思是,表达式`n != 0`应该是`True`,否则,根据程序运行的逻辑,后面的代码肯定会出错。
# `assert`语句本身就会抛出`AssertionError`
# 启动Python解释器时可以用`-O`参数来关闭`assert`: python -O err.py
def foo(s):
    n = int(s)
    assert n != 0, 'n is zero!'
    return 10 / n

def main():
    foo('0')

# 3、 logging
import logging
logging.basicConfig(level=logging.INFO)
s = '0'
n = int(s)
logging.info('n = %d' % n)
print(10 / n)

# 4、 pdb 单步方式运行
# l:查看代码, n:单步执行,p 变量名:查看变量,q:结退出
python -m pdb err.py