Python中的各大器,方便函数的使用,新增函数的方法和用途
一、装饰器
定义:在原有的函数前后,增加功能,且不改变原函数的调用方式
def wrapper(f1): ''' 使用闭包函数用于装饰器的原因是:不想修改原函数的调用方式 ''' def inner(*args,**kwargs): '''执行函数之前的操作''' ret = f1(*args,**kwargs) '''执行函数之后的操作''' return ret return inner #使用装饰器wrapper的方式为 @wrapper def func(): pass
注:在装饰器中的返回值,只能用一个变量将内部的函数返回值接收,如果直接返回函数的返回值,会导致多次执行装饰函数
装饰器的进阶
1、控制装饰器
#需求:控制装饰器的开启和关闭 FLAG=True #全局变量,控制是否开启装饰器 def outer(flag): def wrapper(f1): def inner(*args,**kwargs): if flag: '''执行函数之前的操作''' ret = f1(*args,**kwargs) '''执行函数之后的操作''' else: ret = f1(*args, **kwargs) return ret return inner return wrapper @outer(FLAG) def fun(): pass
2、多个装饰器,装饰函数
def wrapper1(func): def inner(): print('wrapper1 ,before func') func() print('wrapper1 ,after func') return inner def wrapper2(func): def inner(): print('wrapper2 ,before func') func() print('wrapper2 ,after func') return inner @wrapper2 @wrapper1 def f(): print('in f') f() #结果是wrapper2
wrapper1
wrapper1
wrapper2
二、迭代器
引入:
如何从列表和字典中取值
index索引
for循环
凡是可以使用for循环取值的都是可迭代的
可迭代协议:内部含有__iter__方法的都是可迭代的
迭代器协议:内部含有__iter__方法和__next__ 方法的都是迭代器
next方法:只取出当前位置和下一个位置的值
迭代器的优势:1、节省内存,2、用时快:取一个值,就可以进行运算,不用取出所有值,再进行计算
range在py2和py3的区别:
py2中:不管range多少,会生成一个列表,这个列表来存储所有生成的值
py3中:不管range多少,都不会实际的生成任何一个值
迭代器的特性:惰性运算
对迭代器的判断:
from collections import Iterator print(isinstance(range(100000000),Iterator)) #验证range执行之后得到的结果不是一个迭代器
三、生成器
自己写的迭代器就是一个生成器
两种自己写生成器(迭代器)的机制:生成器函数 生成器表达式
凡是带有yield的函数,就是一个生成器函数
def func(): print("#####") yield 1 print("%%%%%%") yield 2 #记录当前所在位置,等待下次next来触发函数的状态 g=func() print("```",next(g)) print("```",next(g)) #生成器的调用执行函数代码的,只返回一个生成器(迭代器) #想要生成器函数执行,需要用next来调用
#yield是个关键字,作用类似return,但是区别于return,yield在函数的执行过程中遇到后,只会暂停函数的运行,
存入到内存中,但是不会将函数终止释放,当下次调用next方法的时候,会在从yield的位置继续运行,并且yield还
可以赋值给变量,并接收send传入的值
#在生成器中传入参数 #计算输入值后的平均值 def average(): sum_money=0 day=0 avg=0 while True: money = yield avg sum_money += money day += 1 avg = sum_money / day g = average() next(g) print(g.send(200)) print(g.send(300))
注:send必须在next方法后运行,不能直接使用