迭代器、天生器、装饰器
一、装饰器
1、函数工具:可以把函数名(不带括号)当成变量去用,关联的值是该函数的内存地址
2、闭包函数=作用域+函数嵌套+函数工具
焦点点:内部函数传参的关系查找是以界说阶段为准
3、什么是闭包函数?
闭包是一个嵌套函数,内层函数挪用了外层函数作用域的变量,外层函数返回值为内层函数名。
实质:为函数wrapper传参的一种方式
“闭”函数指的是该函数是内嵌函数
“包”函数指的是该函数包罗对其外层函数作用域名字的引用
def outer():
x=1
def wrapper():
print(x)
return wrapper
f=outer() #为什么要返回函数名wrapper:打破内嵌函数wapper只能在outer函数内部挪用的规则,使得重回全局挪用
f()
4、闭包函数解决的痛点:当wrapper函数体需要传参,又不能直接通过形参传入时,闭包就可以解决此问题
5、什么是装饰器?
界说一个函数(类),在不改变被装饰函数源代码及挪用方式的情形下为其增添功效。
import time
def target(x,y):
time.sleep(3)
print("my name is {} ,age is {}".format(x,y))
return "ok"
#需求:不改变target函数源代码和挪用方式的情形下统计target函数的运行时间
import time
def outer(func): #func体现闭包的功效,给wrapper函数体传入需要的参数func,为了不改变target源码
def wrapper(*args,**kwargs): #*args,**kwargs被装饰函数需要的参数
start=time.time()
res=func(*args,**kwargs)
end=time.time()
print(end-start)
return res
return wrapper
#target=outer(target) #为了不改变target挪用方式
#偷梁换柱:将target函数名指向的内存地址换成了wrapper
@outer
def target(x,y):
time.sleep(3)
print("my name is {} ,age is {}".format(x,y))
return "ok"
target("lennie",28)#没动源码,也没改变挪用方式
6、无参装饰器模板
def outer(func):
def wrapper(*args,**kwargs):
res=func(*args,**kwargs)
return res
return wrapper
7、有参装饰器
在outer函数外再套一层函数outer2,将outer函数体需要的参数,通过outer2形参传入,即成了有参装饰器。
二、迭代器
1、迭代:每一次对历程的重复称为一次“迭代”,而与单纯的重复差别,每一次迭代获得的效果会作为下一次迭代的初始值。
#重复
while True:
msg = input('>>: ').strip()
print(msg)
#迭代
goods=['mac','lenovo','acer','dell','sony']
index=0
while index < len(goods):
print(goods[index])
index+=1
2、可迭代工具:内置有__iter__()方式的工具都是可迭代工具,字符串、列表、元组、字典、聚集、打开的文件都是可迭代工具,可以直接被for循环遍历。通过obj.__iter__()或者iter(obj)可以返回一个迭代器工具iterator。
3、迭代器:迭代器即用来迭代取值的工具。是Python提供的一种统一的、不依赖于索引的迭代取值方式,只要存在多个“值”,无论序列类型还是非序列类型都可以根据迭代器的方式取值。
4、迭代器工具:内置有__next__()方式的工具,可以通过iterator.__next__()或者next(iterator)取出出迭代器中的下一个值,可以直接被for循环遍历。
>>> s={1,2,3} # 可迭代工具s
>>> i=iter(s) # 本质就是在挪用s.__iter__(),返回s的迭代器工具i,
>>> next(i) # 本质就是在挪用i.__next__()
1
>>> next(i)
2
>>> next(i)
3
>>> next(i) #抛出StopIteration的异常,代表无值可取,迭代竣事
二、天生器
1、什么是天生器/天生器工具?
天生器函数(含yield关键字)的返回值为天生器工具,内置有__iter__()和__next__()方式,以是天生器自己就是一个迭代器,可以直接被for循环遍历。
>>> def my_range(start,stop,step=1):
... print('start...')
... while start < stop:
... yield start
... start+=step
... print('end...')
...
>>> g=my_range(0,3)
>>> g
#直接挪用不执行函数体
>>> g.__iter__
>>> g.__next__
>>> next(g) # 触发函数执行直到遇到yield则住手,将yield后的值返回,并在当前位置挂起函数
start...
0
>>> next(g) # 再次挪用next(g),函数从上次暂停的位置继续执行,直到重新遇到yield...
1
>>> next(g) # 周而复始...
2
>>> next(g) # 触发函数执行没有遇到yield则无值返回,即取值完毕抛出异常竣事迭代
end...
Traceback (most recent call last):
File "", line 1, in
StopIteration
2、什么是天生器函数:
含有yield语句的函数
挪用天生器函数将返回一个天生器工具,不执行函数体
yield翻译为”发生”或”天生”,返回多个工具用yield(迭代),返回一个工具用return
(1) 挪用天生器函数会自动建立迭代器工具。
(2) 挪用迭代器工具的__next__()方式时才执行天生器函数。
(3) 每次执行到yield语句时返回数据,暂时脱离。
(4) 待下次挪用__next__()方式时继续从脱离处继续执行。
3、作用:在循环历程中,根据某种算法推算数据,不必建立容器存储完整的效果,从而节约内存空间。数据量越大,优势越显著。
4、天生器表达式
建立一个天生器工具有两种方式,一种是挪用带yield关键字的函数,另一种就是天生器表达式,与列表天生式的语法花样相同,只需要将[]换成(),即:
>>> [x*x for x in range(3)]
[0, 1, 4]
>>> g=(x*x for x in range(3))
>>> g
at 0x101be0ba0>
>>> next(g) #对比列表天生式,天生器表达式的优点自然是节约内存(一次只发生一个值在内存中)
0
>>> next(g)
1
>>> next(g)
4
>>> next(g) #抛出异常StopIteration
原文链接:https://www.cnblogs.com/lennie-luo/p/12886088.html
本站声明:网站内容来源于网络,若有侵权,请联系我们,我们将及时处理。