异常捕捉
程序可能会出现未知或者难以预料的错误,这时候需要捕捉异常。异常有很多形式,具体不多说,只是记录下工作中常用的一种处理流程,不知道是否合理,但是程序可以这么用。
常见的异常
常见的异常有ValueError、ZeroDivisionError、UnicodeError等。对于有的异常,我们需要及时捕获并且反馈,比如用 python做一个简易的计算器。如果0做分母,则需要告诉用户。有的为了程序的整体运行,可能只需要记载错误,不需要终止所有程序。常见的异常如下:
异常名称 | 描述 |
---|---|
BaseException | 所有异常的基类 |
SystemExit | 解释器请求退出 |
KeyboardInterrupt | 用户中断执行(通常是输入^C) |
Exception | 常规错误的基类 |
StopIteration | 迭代器没有更多的值 |
GeneratorExit | 生成器(generator)发生异常来通知退出 |
StandardError | 所有的内建标准异常的基类 |
ArithmeticError | 所有数值计算错误的基类 |
FloatingPointError | 浮点计算错误 |
OverflowError | 数值运算超出最大限制 |
ZeroDivisionError | 除(或取模)零 (所有数据类型) |
AssertionError | 断言语句失败 |
AttributeError | 对象没有这个属性 |
EOFError | 没有内建输入,到达EOF 标记 |
EnvironmentError | 操作系统错误的基类 |
IOError | 输入/输出操作失败 |
OSError | 操作系统错误 |
WindowsError | 系统调用失败 |
ImportError | 导入模块/对象失败 |
LookupError | 无效数据查询的基类 |
IndexError | 序列中没有此索引(index) |
KeyError | 映射中没有这个键 |
MemoryError | 内存溢出错误(对于Python 解释器不是致命的) |
NameError | 未声明/初始化对象 (没有属性) |
UnboundLocalError | 访问未初始化的本地变量 |
ReferenceError | 弱引用(Weak reference)试图访问已经垃圾回收了的对象 |
RuntimeError | 一般的运行时错误 |
NotImplementedError | 尚未实现的方法 |
SyntaxError | Python 语法错误 |
IndentationError | 缩进错误 |
TabError | Tab 和空格混用 |
SystemError | 一般的解释器系统错误 |
TypeError | 对类型无效的操作 |
ValueError | 传入无效的参数 |
UnicodeError | Unicode 相关的错误 |
UnicodeDecodeError | Unicode 解码时的错误 |
UnicodeEncodeError | Unicode 编码时错误 |
UnicodeTranslateError | Unicode 转换时错误 |
Warning | 警告的基类 |
DeprecationWarning | 关于被弃用的特征的警告 |
FutureWarning | 关于构造将来语义会有改变的警告 |
OverflowWarning | 旧的关于自动提升为长整型(long)的警告 |
PendingDeprecationWarning | 关于特性将会被废弃的警告 |
RuntimeWarning | 可疑的运行时行为(runtime behavior)的警告 |
SyntaxWarning | 可疑的语法的警告 |
UserWarning | 用户代码生成的警告 |
异常处理
try/except语句用来检测try语句块中的错误,从而让except语句捕获异常信息并处理。具体逻辑如下:
try:
<语句> #运行别的代码
except <名字>:
<语句> #如果在try部份引发了'name'异常
except <名字>,<数据>:
<语句> #如果引发了'name'异常,获得附加的数据
else:
<语句> #如果没有异常发生
看一个实际的列子:
try:
print(1/0)
except ZeroDivisionError as e:
print("O 不能做分母")
print("except:",e)
else:
print("运行成功")
O 不能做分母
except: division by zero
但是有的时候我们并不能预料会发生什么样的错误,此时可以用except指代所有的错误,并且把错误写到日志中备查
try:
print(1/0)
except:
print("程序出现异常")
程序出现异常
日志
封装日志函数
日志模块参数比较多,我也没搞懂。实际用的脚本里封装好的一个函数,还是可以用的。
def mylog(logname,logpath):
import logging
# 创建一个日志记录器
log = logging.getLogger("test_logger")
log.setLevel(logging.INFO)
# 创建一个日志处理器
## 这里需要正确填写路径和文件名,拼成一个字符串,最终生成一个log文件
logHandler = logging.FileHandler(filename = logpath+"RiskControlDebugging_"+logname+".log")
## 设置日志级别
logHandler.setLevel(logging.INFO)
# 创建一个日志格式器
formats = logging.Formatter('%(asctime)s %(levelname)s: %(message)s',
datefmt='[%Y/%m/%d %I:%M:%S]')
# 将日志格式器添加到日志处理器中
logHandler.setFormatter(formats)
# 将日志处理器添加到日志记录器中
log.addHandler(logHandler)
return log
利用日志捕捉异常
import os
logname = 'test';logpath = os.getcwd()+"\\"
logger=mylog(logname,logpath)
import sys
try:
print(1/0)
except:
logger.exception(sys.exc_info())
logger.info("Error in dbconfig_file")
f=open('RiskControlDebugging_test.log','r')
print(f.read())
[2018/03/25 05:18:30] ERROR: (<class 'ZeroDivisionError'>, ZeroDivisionError('division by zero',), <traceback object at 0x0000000006EDC5C8>)
Traceback (most recent call last):
File "<ipython-input-4-f4be39498d99>", line 6, in <module>
print(1/0)
ZeroDivisionError: division by zero
[2018/03/25 05:18:30] INFO: Error in dbconfig_file
目前使用的大概是这个形式,直接看文档对我来说还是有点难,所以基本都是看二次加工的,即别人写的博客,希望可以早日拥有直接看文档的能力。
2018-03-25 于杭州