一.内容回顾
反射的另外两个内置函数 setattr delattr
a.b=c 与 setattr(a,'b',c)相对
del a.b 与 delattr(a,'b')
两个内置函数
A,B(A),C(B)
type(c_obj) is C 只能判断出和C的关系
isinstance(c_obj,A) 不仅能判断C,还有AB
issubclass(C,B)
内置方法
__new__ 构造方法
__init__ 初始化方法
__call__ 对象()
__del__ 析构方法 在del对象之后,删除对象之前执行
__str__ 能在打印对象时,不输出无用的内存地址,输出你需要的格式化字符串
__repr__ %r,repr(),做__str__方法的备胎
__eq__(self,other) obj1 == obj2 self 是obj1 ,other 是obj2
# item 使用中括号的形式操作对象,需要完成对应的item系列的方法
__getitem__ obj['xxx'] ==>obj.xxx
__setitem__ obj['xxx']=yyy ==>obj.xxx=yyy
__delitem__ del obj['xxx'] ==> del obj.xxx
二.今日内容
异常处理
认识 错误和异常
常见 异常和错误
如何处理异常
最基础的try...except语法
还有多分支
万能异常
else语法 没有异常执行
finally 不管有没有异常都执行
如何主动抛出异常 raise XXX
*如何定制一个属于自己的异常
断言 assert
hashlib模块 -摘要算法模块 md5算法 sha1算法
解决我们程序中一个非常不安全的因素才出现的
*configparser模块
name #NameError 错误 在写代码的时候杜绝
class A:pass #AttributeError 属性错误
缩进错误 IndentationError
int('abc')# ValueError 错误 int是整型,abc是str字符串
iterator = iter([]) # StopIteration 迭代超过最大范围 next(iterator)
多分支处理,针对不同的错误做不同的处理或者提示
try:
num = int(input('>>>'))
print(l[num-1])
except ValueError:
print('请输入一个数字')
except IndexError:
print('您输入的数字无效')
单分支处理多个异常,问题是无法知道具体的异常种类
try:
num = int(input('>>>'))
print(l[num-1])
except(ValueError,IndexError): 你处理的是一个valueError
print('你输入的内容不合法')
as语句,使用as语句得到一个错误信息的变量,使用这个变量,就可以知道错误的具体信息
try:
num = int(input('>>>'))
print(l[num-1])
except (ValuError,IndexError) as exp :
print('您输入的内容不合法')
print('悄悄记录在文件里,不要被用户发现',type(exp),exp)
在程序最外层添加一个异常处理,处理程序的所有异常
def func(): name def main(): func() try: main() except Exception as e: print('报错了',type(e),e)#报错了 <class 'NameError'> name 'name' is not defined
如果万能异常和其他异常相遇了:万能异常永远写在多分支异常的最后
l=[1,2,3,4] try: num = int(input('>>>')) print(l[num - 1]) a#万能异常
import times except ValueError: # 你处理的是一个valueError print('请输入一个数字') except IndexError: print('您输入的数字无效') except Exception: print('万能异常')
关于万能异常的提醒:所有的异常处理应该用最基础的最贴近的异常类型去处理它,而不应该乱用万能异常
l=[1,2,3,4] try: num = int(input('>>>')) print(l[num - 1]) except ValueError: # 你处理的是一个valueError print('请输入一个数字') except IndexError: print('您输入的数字无效') else: print('执行我啦') # 如果try中的代码没有异常的顺利执行了,就执行else中的代码 # 记录try中的代码顺利执行
finnaly 无论如何都会执行 关闭文件归还系统资源(网络上连接数据库连接)
遇到return 遇到程序报错结束 都会先执行finally,再return或者报错停止运行
try: num = int(input('>>>')) print(l[num - 1]) except ValueError: # 你处理的是一个valueError print('请输入一个数字') except IndexError: print('您输入的数字无效') else: print('执行我啦') finally: # 无论如何都会执行 print('finally')
raise ImportError 主动抛出异常
在抽象类中,通过主动抛异常来约束,使程序员实现指定功能,否则报错
class A: def func(self): raise NotImplementedError class B(A): def func1(self):#func()则只打印B的func,不报错 print('B的func') b = B() b.func()#NotImplementedError
# [][10] # 报错,程序就结束了,并没有记录这个异常 try: [][10] #报错 except Exception as exp: # except Exception print('先记录这个错误,再抛异常',exp,type(exp)) # 先记录异常#list index out of range#<class 'IndexError'> raise type(exp) #IndexError # 把这个异常原封不动的抛出来
什么时候用自定义异常???
import queue q = queue.Queue() print(q.get_nowait()) # queue.Empty
python当中内置的异常 有限的 # 它只跟一些和我们正常开发常见的逻辑相关 循环 基础数据类型 # NameError 存储在内置的命名空间中,内置命名空间在py文件执行的时候,python代码执行之前 # 这些异常是直接存储在内存中 # 有一些和特殊的功能相关的错误,就和这些特殊的功能一起放在模块中,而不是放在内置的命名空间中 # 这些模块是别人写的 class NoCourse(BaseException): def __init__(self,msg): self.msg = msg def __str__(self): return self.msg error = NoCourse('没有这个课程') print(error) class NoCourse(BaseException): def __str__(self): return '没有这个课程' raise NoCourse()
上面自定义了一个错误,两个程序功能是一样的
断言 assert
assert 1==1 # assert bool/条件 如果是False就报错,如果是True就继续执行 print('继续执行')#继续执行 assert True print('cuole')#cuole assert False print('cuole')#因为是False,所以不执行
# assert 'name' == 'alex' and 'pwd' == 'sb' # 这是一个必须满足的条件 # ... # ... # ... # ... # ... # ...