一 异常
1 异常
异常通常可以看做是程序的错误,代表程序是有缺陷的。
异常类型
异常 描述
BaseException 所有异常的基类
SystemExit 解释器请求退出
Exception 常规错误的基类
StopIteration 迭代器没有更多的值
GeneratorExit 生成器(generator)发生异常来通知退出
FloatingPointError 浮点计算错误
OverflowError 数值运算超出最大限制
ZeroDivisionError 除(或取模)零 (所有数据类型)
AttributeError 对象没有这个属性
EOFError 没有内建输入,到达EOF 标记
EnvironmentError 操作系统错误的基类
IOError 输入/输出操作失败
OSError 操作系统错误
WindowsError 系统调用失败
ImportError 导入模块/对象失败
2 异常处理
在Python中,可以使用try语句检查异常,任何在try语句块里的代码都会被检测。try语句主要有两种类型:try-except和try-finally。
异常处理并不仅仅处理那些直接发生在try子句中的异常,而且还能处理子句中调用的函数(甚至间接调用的函数)里抛出的异常。
try-except
def Yichang(list):
print(list[len(list)])
list1 = [0, 1, 2, 3]
def GetExpection():
try:
ch=Yichang(list1)
except IndexError as s:
print(s)
print('列表索引超出范围')
GetExpection()
结果:
list index out of range
列表索引超出范围
一个 try 语句可能包含多个except子句,分别来处理不同的特定的异常。最多只有一个分支会被执行。
处理程序将只针对对应的try子句中的异常进行处理,而不是其他的 try 的处理程序中的异常。
一个except子句可以同时处理多个异常,这些异常将被放在一个括号里成为一个元组
例如:
except (RuntimeError, TypeError, NameError):
pass
在except子句还可以写入else语句。在try子句执行时没有发生异常,python将执行else语句后的语句(可选),然后控制流通过整个try语句。
try:
1/1
except ZeroDivisionError:
print('除数为0的异常')
else:
print('tr无异常y语句')
结果:
tr无异常y语句
使用 else 子句比把所有的语句都放在 try 子句里面要好,这样可以避免一些意想不到的、而except又没有捕获的异常。
try-finally
不管 try 子句里面有没有发生异常,finally 子句都会执行。
格式:try-except-finally 和try-except-else-finally
def Yichang(list):
print(list[len(list)])
list1 = [0, 1, 2, 3]
def GetException():
try:
ch=Yichang(list1)
except IndexError as s:
print(s)
print('列表索引超出范围')
finally:
print('finally。。。。。。')
GetException()
结果:
list index out of range
列表索引超出范围
finally。。。。。。
另外,当try语句中有return语句的时候,会检查是否有finally语句,若有,会先执行finally语句,在执行return。同理,try语句中有exit()也一样。
3 抛出异常
Python 使用 raise 语句抛出一个指定的异常。
raise 唯一的一个参数指定了要被抛出的异常。它必须是一个异常的实例或者是异常的类(也就是 Exception 的子类)。
如果你只想知道这是否抛出了一个异常,并不想去处理它,那么一个简单的 raise 语句就可以再次把它抛出。
try:
raise NameError('HiThere')
except NameError:
print('An exception flew by!')
raise
结果:
An exception flew by!
Traceback (most recent call last):
File “”, line 2, in ?
NameError: HiThere
自定义异常
可以通过创建一个新的异常类来拥有自己的异常。异常类继承自 Exception 类,可以直接继承,或者间接继承。
当创建一个模块有可能抛出多种不同的异常时,一种通常的做法是为这个包建立一个基础异常类,然后基于这个基础类为不同的错误情况创建不同的子类
class sexException(Exception):
pass
def dosex():
sex=input("请输入性别:")
if sex!='男' and sex!='女':
raise sexException("性别只能为男或女")
try:
dosex()
except sexException as se:
print(se)
结果:
请输入性别:我
性别只能为男或女
二 日志
日志是一种可以追踪某些软件运行时所发生事件的方法。软件开发人员可以向所写的代码中调用日志记录相关的方法来表明发生了某些事情。一个事件可以用一个可包含可选变量数据的消息来描述。此外,事件也有重要性的概念,这个重要性也可以被称为严重性级别(level)。
不同的应用程序所定义的日志等级可能会有所差别,分的详细点的会包含以下几个等级:
DEBUG 最详细的日志信息
INFO 信息详细程度仅次于DEBUG,通常只记录关键节点信息
NOTICE
WARNING 当某些不期望的事情发生时记录的信息(警告)
ERROR 由于一个更严重的问题导致某些功能不能正常运行时记录的信息
CRITICAL 当发生严重错误,导致应用程序不能继续运行时记录的信息
ALERT
EMERGENCY
logging模块定义的函数和类为应用程序和库的开发实现了一个灵活的事件日志系统。logging模块是Python的一个标准库模块,由标准库模块提供日志记录API的关键好处是所有Python模块都可以使用这个日志记录功能。
说明:
1 上面列表中的日志等级是从上到下依次升高的,即:DEBUG < INFO < WARNING < ERROR < CRITICAL,而日志的信息量是依次减少的。
2 logging模块也可以指定日志记录器的日志级别,只有级别大于或等于该指定日志级别的日志记录才会被输出,小于该等级的日志记录将会被丢弃。
import logging
# 日志输出格式 时间 日志级别 日志信息
LOG_FORMAT = "%(asctime)s - %(levelname)s - %(message)s"
# 日志保存文件名
logging.basicConfig(filename='aaa.txt',level=logging.DEBUG,format=LOG_FORMAT)
def test():
try:
a=int(input("请输入一个被除数:"))
b=int(input("请输入一个除数:"))
print(a/b)
return
except (ValueError):
#处理异常
logging.debug("只能输入数字!")
except ZeroDivisionError:
logging.info("除数不能为0")
else:
print("else...")
finally:
print("程序结束")
test()
结果:
请输入一个被除数:1
请输入一个除数:0
除数不能为0
程序结束
同时也会在和当前路径下,创建一个文档名为aaa的文档记录该事件。内容如下:
2018-06-26 11:38:48,669 - INFO - 除数不能为0