常见的异常

  • BaseException所有异常的基类
  • KeyboardInterrupt:用户中断执行
  • Exception常规错误的基类
  • StandardError所有内建标准异常的基类
  • ArithmeticError所有数值计算错误的基类
  • AttributeError:对象没有这个属性
  • IOError:输入/输出错误
  • ImportError:导入模块失败
  • IndexError:没有这个索引
  • KeyError:没有这个键
  • NameError:没有初始化这个对象
  • RuntimeError:运行错误
  • SyntaxError:语法错误
  • IndentationError:缩进错误
  • TypeError:对类型无效的操作
  • ValueError:传入无效的参数
  • Warning所有警告的基类
  • DeprecationWarning:关于被弃用特征的警告
  • FutureWarning:关于构造将来语义会有改变的警告
  • RuntimeWarning:运行警告
  • SyntaxWarning:语法警告

异常的捕获

  • try except语句

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    import sys

    try: # 尝试执行可能发生异常的语句
    with open('myfile.txt', 'r', encoding='utf-8') as f:
    s = f.readline()
    i = int(s.strip())
    except OSError as err: # 捕获输入输出错误
    print('OS error: {}'.format(err))
    except ValueError: # 捕获无效参数
    print('Could not convert data to integer.')
    except: # 捕获其它错误,并输出错误信息
    print('Unexpected error:', sys.exc_info()[0])
  • try except else

    1
    2
    3
    4
    5
    6
    7
    try:
    f = open('myfile.txt', 'r')
    except IOError: # 发生异常时执行的代码
    print('Can not open file.')
    else: # 没有发生异常时执行的代码
    print('File has {} lines'.format(len(f.readlines())))
    f.close()
  • finally语句:无论是否发生异常都会执行

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    try:
    f = open('myfile.txt', 'w', encoding='utf-8')
    i = int(input('Please input something:'))
    except ValueError:
    print('Could not convert data to integer.')
    else:
    f.write(str(i))
    finally:
    print('Close file.')
    f.close()

抛出异常

  • raise语句

    1
    2
    3
    x = 2
    if x > 1:
    raise Exception('Invalid value: {}'.format(x))

自定义异常

  • 异常的本质是一个类

    1
    2
    3
    4
    5
    6
    7
    8
    class MyError(Exception):
    def __init__(self, value):
    self.value = value

    try:
    raise MyError(5)
    except MyError as e:
    print('MyError occured, value: {}'.format(e.value))

日志模块

  • logging模块用于处理日志

  • logging.getLogger:创建记录器

  • logging.setLevel:设置日志级别

  • logging.FileHandler:创建日志文件

  • logging.StreamHandler:将日志输出到控制台

  • logging.Formatter:设置日志格式

  • addHandler:将日志处理程序添加到记录器

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    import logging

    logger = logging.getLogger(__name__)
    logger.setLevel(logging.DEBUG)

    ch = logging.StreamHandler()
    ch.setLevel(logging.WARNING)

    fh = logging.FileHandler('debug.log')
    fh.setLevel(logging.DEBUG)

    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    ch.setFormatter(formatter)
    fh.setFormatter(formatter)

    logger.addHandler(ch)
    logger.addHandler(fh)

    logger.info('info message')
    logger.debug('debug message')
    logger.warning('warning message')
    logger.error('error message')
    logger.critical('critical message')

捕获异常并记录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import logging
import os, sys
import time

class Logger(object):
def __init__(self, level='INFO', name=os.path.split(os.path.splitext(sys.argv[0])[0])[-1], log_name=time.strftime('%Y-%m-%d.log', time.localtime()), log_path=os.path.join(os.path.dirname(os.path.abspath(os.__file__)), 'log'), use_console=True):
"""
:param level:日志级别
:param name:日志中打印的name,默认为程序名
:param log_name:日志文件的名字,默认为当前日期
:param log_path:日志文件夹的路径,默认为Logger类所在python脚本的同级目录中的log文件夹
:param use_console:是否在控制台打印,默认打印
"""
if not os.path.exists(log_path):
os.makedirs(log_path)

self.logger = logging.getLogger(name)
self.logger.setLevel(level)

formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

handler_list = []
handler_list.append(logging.FileHandler(os.path.join(log_path, log_name), encoding='utf-8'))
if use_console:
handler_list.append(logging.StreamHandler())

for handler in handler_list:
handler.setFormatter(formatter)
self.logger.addHandler(handler)

def info(self, message):
self.logger.info(message)

def debug(self, message):
self.logger.debug(message)

def warning(self, message):
self.logger.warning(message)

def error(self, message):
self.logger.error(message)

def critcal(self, message):
self.logger.critical(message)

if __name__ == '__main__':
mylog = Logger()
try:
open('file.txt', 'w')
except Exception as e:
mylog.error(e)