假期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不能接受新的值

计算移动平均值的例子

预计生成器的装饰器的例子

posted @ 2021-01-18 23:19  20181235  阅读(38)  评论(0编辑  收藏  举报