user_info = { 'user': None } #登陆功能认证 def login(): username = input('请输入帐号名:').strip() password = input('请输入密码:').strip() with open(r'a.txt', 'r', encoding='utf-8')as f: for line in f: f.readline() name, pwd = line.strip('\n').split(':')#交叉赋值返回的是['yafeng','666'] if username == name and password == pwd: print('登陆成功!') user_info['user'] = username else: print('登陆失败!') def login_auth(func): def inner(*args, **kwargs): #已经登陆,将被装饰对象直接调用并返回 if user_info.get('user'):#若是在列表里 res = func(*args, **kwargs) return res else: print('请先登陆') login() ''' 注意: 不管inner中出现任何判断, 最后都要返回“调用后的被装饰对象” func(*args, **kwargs) ''' res = func(*args, **kwargs)#注意此时必定要返回res,不然from 1 打印不出来 return res return inner @login_auth def func1(): print('from 1') pass @login_auth def func2(): print('from 2') pass @login_auth def func3(): print('from 3') pass while True: func1() input('请输入操做') func2() func3()
有的时候咱们想要对一个被装饰函数进行多功能的装饰,虽然咱们也能够在一个装饰器中去添加多个功能,但这样就会显得代码很长,可读性不高,并且若是之后咱们又想修改这个装饰器函数的功能,咱们还得去删除,咱们最好的方法就是一个装饰器就固定哪个功能,咱们想要对函数进行多此装饰,那么此时叠加装饰器就派上用场了。python
在同一个被装饰对象中,添加多个装饰器,并执行。 @装饰1 @装饰2 @装饰3 def 被装饰对象(): pass 注意:叠加装饰器的顺序*****(重要) 装饰的顺序:由下到上装饰 执行的顺序:由上往下
def wrapper1(func): def inner1(*args, **kwargs): print('1---start') # 被裝飾對象在調用時,若是還有其余裝飾器,會先執行其余裝飾器中的inner # inner2 res = func(*args, **kwargs) print('1---end') return res return inner1 def wrapper2(func): def inner2(*args, **kwargs): print('2---start') res = func(*args, **kwargs) print('2---end') return res return inner2 def 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() >>>1---start 2---start 3---start from index... 3---end 2---end 1---end
以前咱们用的都是无参装饰器,就是在装饰被装饰对象时,没有传参app
''' # 如下是无参装饰器 @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(): pass index()
''' wraps: (了解) 是一个修复工具,修复的是被装饰对象的空间。 from functools import wraps ''' from functools import wraps def wrapper(func): @wraps(func) # 修更名称空间: inner ---》 func def inner(*args, **kwargs): ''' 此处是装饰器的注释 :param func: :return: ''' res = func(*args, **kwargs) return res return inner # ---》 func @wrapper def index(): ''' 此处是index函数的注释 :return: ''' pass print(index) # 函数对象 # 函数对象.__doc__: 查看函数内部的注释 print(index.__doc__) # inner.__doc__
迭代:迭代是一个重复的过程,而且每次重复都是基于上一次的结果而来函数
x = 10 while True: print(x) #这虽然是重复过程,但并无基于上一次的结果 l = [1,2,3,4] n = 0 while n < len(l): print(l[n]) n += 1 >>>1 2 3 4 #这才是一个迭代,每次结果基于上一次
要想了解迭代,咱们还得先了解什么是可迭代对象工具
在python中,但凡内置有._iter_()方法的对象都叫可迭代对象因此如下都是可迭代对象: str list dict tuple set file
了解了什么是可迭代对象的概念后咱们就能够给迭代器下定义了,迭代器指的是更新取值的工具。code
知道了什么是迭代器,什么是可迭代对象之后,咱们就能够去说什么是迭代器对象对象
迭代器对象:索引
可迭代的对象执行._iter_()方法获得的返回值就是迭代器对象,接下来咱们在用获得的迭代器对象.__next__()就能够去获取每一个元素的值了ip
s = {1, 2, 3} iter_s = s.__iter__()#iter_s就是迭代器对象 print(iter_s.__next__()) print(iter_s.__next__()) print(iter_s.__next__()) print(iter_s.__next__()) >>>Traceback (most recent call last): File "D:/python的pycharm/正式课/day12/迭代器.py", line 53, in <module> print(iter_s.__next__()) StopIteration 1 2 3
上面咱们虽然拿到了每一个集合中的元素,但会报错,就是有个StopIteration的错误,该错误指的是当我打印的值超过了个人一个容器中的全部容量的时候会报错,由于已经没有对象让咱们访问了,那此时咱们能不能即能获取到里面的全部元素,也不报错呢,答案是确定的。这时就须要用到try内存
s = {1, 2, 3} iter_s = s.__iter__()#iter_s就是迭代器对象 while True: try: print(iter_s.__next__()) except StopIteration: break >>>1 2 3
总结比比较utf-8
可迭代的对象:
特色:内置有——iter——方法的,就都是可迭代的对象,执行该方法会获得一个迭代器对象
迭代器对象的特色:
内置有——next——方法,每一次执行会拿到迭代器对象中的一个值
内置有——iter——方法,执行会获得迭代器自己
迭代器的特色:
优势:提供了一种不依赖于索引取值的方法
迭代器会更加节省空间内存
缺点:取值麻烦,只能一个一个取
没法使用len去获取某个具体的值