1.装饰器补充
1.叠加装饰器
-
装饰的顺序: 由下到上装饰
-
执行的顺序: 由上往下
def wrapper1(func): def inner1(*args, **kwargs): print('1---start') # 被裝飾對象在調用時,如果還有其他裝飾器,會先執行其他裝飾器中的inner # inner2 res = func(*args, **kwargs) print('1---end') return res return inner1def wrapper2(func): def inner2(*args, **kwargs): print('2---start') res = func(*args, **kwargs) print('2---end') return res return inner2def wrapper3(func): def inner3(*args, **kwargs): print('3---start') res = func(*args, **kwargs) print('3---end') return res return inner3'''叠加裝飾器的裝飾順序與執行順序: - 裝飾順序: 调用wrapper装饰器拿到返回值inner 由下往上裝飾 - 執行順序: 调用装饰过后的返回值inner 由上往下執行'''@wrapper1 # index《---inner1 = wrapper1(inner2)@wrapper2 # inner2 = wrapper2(inner3)@wrapper3 # inner3 = wrapper3(index)def index(): # 被裝飾對象 # inner1 ---》 print('from index...')# 正在装饰# inner3 = wrapper3(index)# inner2 = wrapper2(inner3)# inner1 = wrapper1(inner2)'''inner1()inner2()inner3()index()'''index() # 此处执行 # inner1() --> inner2() ---> inner3()
2.有参装饰器
# 无参装饰器: 装饰在被装饰对象时,没有传参数的装饰器。'''# 以下是无参装饰器@wrapper1 # inner1 = wrapper1(inner2)@wrapper2 # inner2 = wrapper2(inner3)@wrapper3'''# 有参装饰器:装饰在被装饰对象时,传参数的装饰器。# 有参装饰器: 在某些时候,我们需要给用户的权限进行分类'''# 以下是有参装饰器@wrapper1(参数1) # inner1 = wrapper1(inner2)@wrapper2(参数2) # inner2 = wrapper2(inner3)@wrapper3(参数3)'''# 有参装饰器def user_auth(user_role): # 'SVIP' def wrapper(func): def inner(*args, **kwargs): if user_role == 'SVIP': # 添加超级用户的功能 res = func(*args, **kwargs) return res elif user_role == '普通用户': print('普通用户') # 添加普通用户的功能 res = func(*args, **kwargs) return res return inner return wrapper# 被装饰对象# @user_auth('SVIP')wrapper = user_auth('普通用户')@wrapper# @user_auth('SVIP') # wrapper = user_auth('普通用户')@wrapper #<--- 返回结果(wrapper) <---- user_auth()def index(): passindex()
补充:
'''wraps: (了解) 是一个修复工具,修复的是被装饰对象的空间。 from functools import wraps'''from functools import wrapsdef wrapper(func): @wraps(func) # 修改名称空间: inner ---》 func def inner(*args, **kwargs): ''' 此处是装饰器的注释 :param func: :return: ''' res = func(*args, **kwargs) return res return inner # ---》 func@wrapperdef index(): ''' 此处是index函数的注释 :return: ''' passprint(index) # 函数对象# 函数对象.__doc__: 查看函数内部的注释print(index.__doc__) # inner.__doc__
2.迭代器
1.什么是迭代器
迭代器就是指迭代取值的工具,迭代就是指重复反馈过程的活动,每一次对过程的重复就是迭代,而每一次迭代的结果会作为下一次迭代的初始值,单纯的重复不是迭代
2.什么是可迭代对象
凡是内部有.__ iter __()方法的都是可迭代对象,比如序列类型为:str, list, tuple, dict ,set, f(打开的文件). 等
str1.__iter__()list1 = [1, 2, 3] # list([1, 2, 3])list1.__iter__()set.__iter__()dict.__iter__()tuple.__iter__()open('a.txt').__iter__()
3.什么是迭代器对象
调用obj.__ iter __()方法返回的结果就是一个迭代器对象(Iterator)
注意:可迭代对象依赖索引取值,迭代器对象不依赖索引取值
# 依赖索引取值l1 = [1, 2, 3]n = 0while n < len(l1): print(l1[n]) n += 1# 不依赖索引取值l1 = [1, 2, 3]iter_l1 =l1.__iter__()while True: print(iter_l1.__next__()) # 当迭代器对象里面的元素被拿就会报错,下面这种方法可以改善l1 = [1, 2, 3]iter_l1 =l1.__iter__()while True: try: # 通过try捕获异常 print(iter_l1.__next__()) # 立即触发此处代码 StopIteration except StopIteration: breaklist1 = [1, 2, 3, 4]for line in list1: # list1是可迭代对象 ----> 内部会自动调用.__iter__() ---> 迭代器对象--->调用try,except stopiteration,brek等完整的拿到全部数据 # 迭代器对象.__next__() print(line)
# 注意:确定: 迭代器对象也是一个可迭代对象l1 = [1, 2, 3, 4]iter_l1 = l1.__iter__()print(iter_l1.__iter__() is iter_l1)True# 可迭代对象不一定是迭代器对象l1 = [1, 2, 3, 4]iter_l1 = l1.__iter__()print(iter_l1 is l1)False注意: 唯独文件比较特殊: 因为文件从读取出来的时候就是一个迭代器对象# f ---> 可迭代对象, 还是迭代器对象f = open('user.txt', 'r', encoding='utf-8')# 确定: 文件既是可迭代对象,也是迭代器对象。# iter_f ---> 迭代器对象# iter_f = f.__iter__()print(iter_f is f) # True