# 迭代器: 访问集合元素的一种方法。从第一个开始访问,直至所有元素都被访问、[只能向前,不可后退]
# 有两个方法:iter()生成迭代器, next()返回迭代器的下一个元素
# 迭代器和for类似:
#----------用迭代器
list23 = [1,2,3,4,5,6,7,8]
it = iter(list23) #创建一个迭代器对象
# print(next(it)) #输出每一个值 1
# print(next(it)) #输出每一个值 2
# #----------用for循环---
# for i in it:
# print(i) #输出每一个值 3\4\5\6\7\8
#===next(迭代对象it, 默认参数) ;没有下一个参数时返回默认,没有设置默认参数时,触发StopIteration异常
i=0
while i<9:
try:
print(next(it))
except StopIteration: #触发异常
print("走完了") #输出:12345678走完了
i=i+1
'''python的迭代器本质上都是调用__next()__方法,且返回下一个元素或触发StopIteration异常的容器对象
想定义一个类,并将其当做迭代器使用时,需要在其中实现__iter__()和__next__()方法.'''
class iterclass:
def __iter__(self):
return self
def __init__(self,count):
self.count = count
def __next__(self):
a = self.count
if a>0:
self.count = self.count - 1
return a
else:
raise StopIteration #a小于0 时抛出异常 如果不希望触发异常,可以给next默认值
#----------调用类iterclass---
it = iterclass(5)
print(next(it)) #5
print(next(it)) #4
print(next(it)) #3
print(next(it)) #2
#生成器: 也是迭代器. 特殊处:提供了延迟操作.可以在需要的时候才产生结果,而不是立即产生结果
'''试想迭代一个列表,数据不多的时候占用系统资源可以忽略不计.迭代器即可.
若是遍历有1个亿元素的列表,占用资源就会很大了甚至崩溃.
生成器:不直接遍历1个亿的元素列表,而是遍历到该元素时通过生成器生成该元素'''
def func(count):
i = 0
a = 0
b = 1
while True:
yield a #保存a的状态|用yield 定义一个生成器.调用时,每次遇到yield就会暂停执行,保存当前所有的运行
# 信息并返回yield的值.在下一次执行next()方法时,从当前位置继续执行
a,b =b, a+b #不能携程a=b,b=a+b 否则b就是赋值后的值
# a=b
# b=b+a # 改成这样,输出结果不一样:0 1 2 4 8 16 32 64 128 256 512
i = i+1
if i>count:
break
#===============================
print(type(func(10))) #输出:<class 'generator'>
f = func(10) #由生成器返回生成迭代器
while True:
try:
print(next(f),end=" ") #输出:0 1 1 2 3 5 8 13 21 34 55
except StopIteration:
break
# 装饰器 :在不修改源代码的前提下,给函数增加新的功能. 其返回值时一个函数.
# 使用场景:日志管理,事务处理,性能测试,缓存及权限校验场景
import time
#====================不带参数的装饰器===============================
# 装饰器函数
def testfunc(f):
starttime = time.time()
f() #执行传入的f参数
endtime = time.time()
msecs = (endtime-starttime)*1000
print("执行时间 %d ms"%msecs)
#---------------使用装饰器testfunc 测试函数执行时间--------------------
@testfunc #使用testfunc装饰器,并将func()函数作为参数传递
def func():
# time.sleep(3) #执行时间 3004 ms 这里不需要显示调用函数func()
pass
#====================带参数的装饰器=================测试的时候可以做测试数据以测试结果=========
# 原函数需要传递参数时.可在装饰器内嵌套一个函数用于接收并处理参数.**参数名与原函数名一致**
def testfunc1(f):
def newfunc(str): #接收参数,与原函数保持一致
print("我是装饰器里的函数哦 "+str)
return newfunc
@testfunc1
def func(str):
print(str)
func("你在哪儿呢") #输出:我是装饰器里的函数哦 你在哪儿呢
#====================多个函数使用同一装饰器==========每个函数的参数数量都不一致========
# 传入不定长的参数.可以将嵌套函数的参数设置为 *args 和 **kwargs 接收任意数量和类型的参数
def testfuncMore(f):
def newfunc(*args,**kwargs): #可接收任意数量和类型的参数
print("我路过了装饰器,却没遇见你")
f(*args,**kwargs)
return newfunc
#--------------------------
@testfuncMore
def func(str):#一个参数
print(str)
@testfuncMore
def func1(name,str):#两个参数
print(name,str)
func("你好")
func1("张三","你吃了吗")
#====================一个函数使用多个装饰器===========
"""# 此处展示多个装饰器的写法,因参数问题,此段代码不能执行=======
@testfunc #函数头上多戴几个装饰器的帽子即可
@testfuncMore
def func1(name,str):#两个参数
print(name,str)
"""