十六.嵌套三层函数的装饰器,迭代器

一.嵌套三层函数的装饰器(有参装饰器)

案例:

import time
def outter1(func):
	def wrapper(*args,**kwargs):
		start = time.time()
		res=func(*args,**kwargs)
		stop = time.time()
		print(stop-start)
		return res
	return wrapper 
# @函数的内存地址1(1,2,3,4,5)  # 函数的内存地址(index)
def index(x,y):
	print('index===>',x,y)
	
@outter1
def home(name):
	print('home====>',name)

引出两个点:

1.可以通过闭包的方式为函数体传参,可以包一层,也可以包两层
2.@后面跟的必须是一个函数的内存地址
	@函数的内存地址(1,2,3)是可以的,但是前提是调用函数'函数的内存地址(1,2,3)'的返回值必须是一个函数的内存地址

示范1:

无参装饰器

def outter(func):
	def wrapper(*args,**kwargs):
		inp_name=input('your name==>').strip()
		inp_pwd=input('your password==>').strip()
		with open('user.txt','rt',encoding='utf-8')as f:
			for line in f:
				name_db,pwd_db=line.strip().split(":")
				if inp_name == name_db and inp_pwd == pwd_db:
					print('login successful')
					res = func(*args,**kwargs)
					return res
			else:
				print('账号或密码错误')
	return wrapper

@outter
def index(x,y):
	print('index==>',x,y)

index(1,2)

示范2:

有参装饰器(仍需改进)

# ldap
# mysql
# file

def outter2(mode):
	def outter(func):
		def wrapper(*args,**kwargs):
			inp_name=input('your name==>').strip()
			inp_pwd=input('your pwd==>').strip()
			if mode == 'file':
				print('认证来源===>file')
				with open('user.txt','rt',encoding='utf-8')as f:
					for line in f:
						name_db,pwd_db=line.strip().split(":")
						if inp_name == name_db and inp_pwd:
							print('login successful')
							res = func(*args,**kwrgs)
							return res
					else:
						print("账号或密码错误")
			elif mode == 'ldap':
				print('认证来源===>ldap')
			elif mode == 'mysql':
				print('认证来源===>mysql')
			else:
				print('未知的认证来源')
		return wrapper
	return outter

outter=outter2(mode='mysql')

@outter # index=outter(index) ==> index=wrapper
def index(x,y):
	print('index===>',x,y)

index(1,2) # wrapper(1,2)



示范3:

改正后的有参装饰器

def outter2(mode):
	def outter(func):
		def wrapper(*args,**kwargs):
			inp_name=input('your name==>').strip()
			inp_pwd=input('your password==>').strip()
			if mode == 'file':
				print('认证来源==>file')
				with open('user.txt','rt',encoding='utf-8')as f:
					for line in f:
						name_db,pwd_db=line.strip().split(":")
						if inp_name == name_db and inp_pwd == pwd_db:
							print('login successful')
							res = func(*args,**kwargs)
							return res
					else:
						print('账号或密码错误')
			elif mode == 'ldap':
				print('认证来源==>ldap')
			elif mode == 'mysql':
				print('认证来源==>mysql')
			else:
				print('未知的认证来源')
		return wrapper 
	return outter 

@outter2(mode='mysql') # index=outter(index) ==>index=wrapper
def index(x,y):
	print('index===>',x,y)

index(1,2)  # wrapper(1,2)

二.迭代器

1.什么是迭代器?

迭代是一个重复的过程,每一次重复都是基于上一次的结果而来的
注意:迭代不是单纯的重复

迭代器是一种迭代取值的工具,这种取值方式是通用,不依赖于索引

str === > 索引
list === > 索引
tuple === > 索引
t = (111,222,333,444,555,666)
i = 0
while i < len(t):
	print(t[i])
	i+=1
dict === > key
set === > 既没有key也没有索引
f 文件对象 == > 既没有key也没有索引

python 为上述类型都内置了__iter__方法

s = 'hello'
ll = [111,222,333]
t = (1111,2222,3333,4444,5555)
d = {'k1':111,'k2':222,'k3':333}
s1 = {'a','b','c'}
f = open(r'user.txt',mode='rt',encoding='utf-8')
f.close()

# 调用 __iter__方法得到的返回值就是对应的迭代器
res = d.__iter__() # res = iter(d)
print(res)  # res 是迭代器
a = res.__next__() # a=next(res)
b = res.__next__() # b=next(res)
c = res.__next__() # c=next(res)
#d = res.__next__() # stopiteration
print(c)

d = {'k1':111,'k2':222,'k3':333}
iter_d = iter(d)

while True:
	try:
		print(next(iter_d))
	except StopIteration:
		break

可迭代的对象:有__iter__内置方法的对象都是可迭代的对象,str,list,tuple,dict,set,文件对象
ps: 可迭代对象.iter()返回的是迭代器对象

迭代器对象:

1.有__next__方法
2.有__iter__方法,调用迭代器的__iter__方法得到的就是迭代器自己
ps: 迭代器对象之所内置__iter__方法是为了符合for循环第一个工作步骤
f = open(r'user.txt',mode='rt',encoding='utf-8')
line = f.__next__()
print(line)
line = f.__next__()
print(line)
for line in f:
	print(line)

f.close()
# line = f.__next__()  # 报错

d = {'k1':111,'k2':222,'k3':333}
res = d.__iter__()

print(res) #<dict_keyiterator object at 0x000002BDA81EE590>
print(res.__iter__())  #<dict_keyiterator object at 0x000002BDA81EE590>
print(res.__iter__() is res)  #True
print(res.__iter__().__iter__().__iter__() is res) #True

2.for循环的工作原理=> 迭代器循环

d = {'k1':111,'k2':222,'k3':333}

for k in d:
	print(k)

for 循环的工作步骤

1.调用in后的对象的__iter__方法,得到对应的迭代器
2.k = next(迭代器),然后执行一次循环
3.循环往复,直到把迭代器的值取干净了,抛出异常,for循环会自动捕捉异常,
结束循环

3.总结迭代器:

优点:

1.不依赖索引,是一种通用的取值方式
2.节省内存
d = {'k1':111,'k2':222,'k3':333}
iter_d = iter(d)

print(next(iter_d))

缺点:

1.不能取指定位置的值
ll = [111,222,333]
print(ll[2])   # 333

iter_ll=iter(ll)
next(iter_ll)
next(iter_ll)
print(next(iter_ll)) # 333
2.不能预估值的个数,无法统计长度
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值