假期python复习
昨天复习
迭代器:
双下方法:很少直接调用的方法。一般情况下,是通过其他的语法触发
可迭代的 ------- 可迭代协议含有____iter___方法 判断方法运用dir进行判断
可迭代的一定可以被for循环
迭代器协议:含有__ iter 和 __ next __ 方法
迭代器一定可迭代,可迭代的通过调用iter()方法就可以得到一个迭代器
迭代器的特点:
1、方便使用,且只能取所有的数据取一次
2、节省内存空间
生成器
生成器的本质就是迭代器
生成器的表现形式:1、生成器函数2、生成器表达式
生成器函数:含有yield关键字的函数就是生成器函数
特点:调用这个函数之后函数不执行,返回一个生成器
每次调用next方法的时候会取到一个值,直到取完最后一个在执行next的会报错
def generator():
print(123)
yield 1
print(456)
yield 2
print(789)
这种情况当执行yield 2 后在next就报错
send的效果和next一样
只是在获取下一个值的时候,给上一值得位置传递一个数据
使用send的注意事项
1、第一次使用生成器的时候是用next获取下一个值
2、最后一个yield不能接收外部的值
获取移动平均值
# def generator():
# print(123)
# yield 1
# print(456)
# yield 2
# print(789)
#
#
# a = generator()
# print(a.__next__())
# print(a.send(None))
#avg = sum/count
def average():
sum = 0
count = 0
avg = 0
# num = yield
while True:
num = yield avg
sum += num
count +=1
avg = sum/count
avg_g = average()
avg_g.__next__()
avg_g.send(10)
avg_g.send(5)
reg = avg_g.send(1)
print(reg)
num = yield avg放在上面可以有效的解决0/0的错误
生成器加装饰器:
def init(func):
def inner(*args,**kwargs):
g=func(*args,**kwargs)
g.__next__()
return g
return inner
@init
def average():
sum = 0
count = 0
avg = 0
# num = yield
while True:
num = yield avg
sum += num
count +=1
avg = sum/count
avg_g = average()
ret = avg_g.send(10)
print(10)
ret = avg_g.send(20)
print(ret)
生成器拓展 将文件内含有pyhton的文件名输出
import os
def init(func):
def wrapper(*args,**kwargs):
g=func(*args,**kwargs)
next(g)
return g
return wrapper
@init
def list_files(target):
while 1:
dir_to_search=yield
for top_dir,dir,files in os.walk(dir_to_search):
for file in files:
target.send(os.path.join(top_dir,file))
@init
def opener(target):
while 1:
file=yield
fn=open(file)
target.send((file,fn))
@init
def cat(target):
while 1:
file,fn=yield
for line in fn:
target.send((file,line))
@init
def grep(pattern,target):
while 1:
file,line=yield
if pattern in line:
target.send(file)
@init
def printer():
while 1:
file=yield
if file:
print(file)
g=list_files(opener(cat(grep('python',printer()))))
g.send('/test1')
协程应用:grep -rl /dir
tail&grep
python3新功能
def generator():
a = 'abcde'
b = '12345'
yield from a
yield from b
g=generator()
for i in g:
print(i)
结果分个返回用yield from self
send
1、第一次不能用send
2、函数中的最后一个yield不能接受新的值
计算移动平均值的例子
预计生成器的装饰器的例子