异常处理及反射
一、异常处理
python异常: python的运行时错误称作异常
1. 语法错误:软件的结构上有错误而导致不能被解释器解释或不能被编译器编译
2. 逻辑错误:由于不完整或不合法的输入所致,也可能是逻辑无法生成、计算或者输出结果需要的过程无法执行等
python异常是一个对象,表示错误或意外情况
(1)在python检测到一个错误时,将触发一个异常
python可以通常异常传导机制传递一个异常对象,发出一个异常情况出现的信号
程序员也可以在代码中手动触发异常 raise Exception
(2)python异常也可以理解为:程序出现了错误而在正常控制流以外采取的行为
第一阶段:解释器触发异常,此时当前程序流将被打断
第二阶段:异常处理,如忽略非致命错误、减轻错误带来的影响等
检测和处理异常:
(1)异常通过try语句来检测
任何在try语句块里的代码都会被检测,以检查有无异常发生
(2)try语句主要有两种形式:
try-except# 检测和处理异常
可以有多个except
支持使用else子句处理没有探测异常的执行的代码
try-finally# 仅检查异常并做一些必要的清理工作
仅能有一个finally
(3)try语句的复合形式:
try-execpt-else-finally
2、异常种类
python中的异常种类非常多,每个异常专门用于处理某一项异常
AssertionError # 断言语句失败
AttributeError # 属性引用或赋值失败
FloatingPointError # 浮点型运算失败
IOError # I/O操作失败
ImportError # import语句不能找到要导入的模块,或者不能找到该模块特别请求的名称
IndentationError # 解析器遇到了一个由于错误的缩进而引发的语法错误
IndexError # 用来索引序列的证书超出了范围
KeyError # 用来索引映射的键不再映射中
keyboardInterrupt # 用户按了中断键(Ctrl+c,Ctrl+Break或Delete键)
MemoryError # 运算耗尽内存
NameError # 引用了一个不存在的变量名
NotImplementedError # 由抽象基类引发的异常,用于指示一个具体的子类必须覆盖一个方法
OSError # 由模块os中的函数引发的异常,用来指示平台相关的错误
OverflowError # 整数运算的结果太大导致溢出
SyntaxError # 语法错误
SystemError # python本身或某些扩展模块中的内部错误
TypeError # 对某对象执行了不支持的操作
UnboundLocalError #引用未绑定值的本地变量
UnicodeError 在Unicode的字符串之间进行转换时发生的错误
ValueError #应用于某个对象的操作或函数,这个对象具有正确的类型,但确有不适当的值
WindowsError #模块os中的函数引发的异常,用来指示与WIndows相关的错误
ZeroDivisionError # 除数为0
实例:IndexError
dic = ["python", 'linux']
try:
dic[10]
except IndexError as e:
print(e)
万能异常 在python的异常中,有一个万能异常:Exception,他可以捕获任意异常,默认不建议这么用,对于特殊处理或提醒的异常需要先定义,最后定义Exception来确保程序正常运行即:
s1 = 'hello'
try:
int(s1)
except Exception as e:
print(e)
3、异常其他结构
try:
# 主代码块
pass
except KeyError as e:
# 异常时,执行该块
pass
else:
# 主代码块执行完,执行该块
pass
finally:
# 无论异常与否,最终执行该块
pass
4、主动触发异常
try:
raise Exception('错误了。。。')
except Exception as e:
print(e)
5、自定义异常
class MyException(Exception):
def __init__(self, msg):
self.message = msg
def __str__(self):
return self.message
try:
raise MyException('我的异常')
except TestException as e:
print(e)
6、断言
# assert 条件
assert 1 == 1
assert 1 == 2
二、反射
python中的反射功能是由以下四个内置函数提供:hasattr、getattr、setattr、delattr、import(module_name),改四个函数分别用于对对象内部执行:检查是否含有某成员、获取成员、设置成员、删除成员、导入模块以字符串方式导入。
class Foo(object):
def __init__(self):
self.name = 'python'
def func(self):
return 'func'
obj = Foo()
# #### 检查是否含有成员 ####
hasattr(obj, 'name')
hasattr(obj, 'func')
# #### 获取成员 ####
getattr(obj, 'name')
getattr(obj, 'func')
# #### 设置成员 ####
setattr(obj, 'age', 18)
setattr(obj, 'show', lambda num: num + 1)
# #### 删除成员 ####
delattr(obj, 'name')
delattr(obj, 'func')
详细解析:
当我们要访问一个对象的成员时,应该是这样操作:
class Foo(object):
def __init__(self):
self.name = 'python'
def func(self):
return 'func'
obj = Foo()
# 访问字段
obj.name
# 执行方法
obj.func()
需求:请使用其他方式获取obj对象中的name变量指向内存中的值 “python”
class Foo(object):
def __init__(self):
self.name = 'python'
# 不允许使用 obj.name
obj = Foo()
答:有两种方式,如下:
class Foo(object):
def __init__(self):
self.name = 'python'
def func(self):
return 'func'
# 不允许使用 obj.name
obj = Foo()
print obj.__dict__['name']
第二种:
class Foo(object):
def __init__(self):
self.name = 'python'
def func(self):
return 'func'
# 不允许使用 obj.name
obj = Foo()
print getattr(obj, 'name')