zoukankan      html  css  js  c++  java
  • Python全栈之路Day21

    初次编辑2017年10月27日,星期五

    摘要

    引用:Alex

    1. 迭代器
    2. 生成器
    3. 协程函数

    一. 上节课复习

    1. 装饰器
      1. 无参装饰器
      2. 有参装饰器
    2. 装饰器打印原函数信息
    import time
    from functools import wraps        #注意这个
    def timmer(func):
        @wraps(func)        #还有这个
        def wrapper():
            start_time = time.time()
            func()
            stop_time = time.time()
            print('run time is %s ' % (stop_time - start_time))
        return wrapper
    
    @timmer        #index=timmer(index)
    def index():
        'come from index'
        print('welcome to oldboy')
    
    index()        #wrapper()
    print(index.__doc__)        #.__doc__打印函数描述信息,具体不是很了解

    二. 迭代器

    1. 可迭代的
      • 只要对象本身有__iter__方法,那它就是可迭代的
    2. 迭代器
      • i = a.iter() #i 即为迭代器
      • 可通过__next__ 进行取值
    b = {'a':1,'b':2,'c':3}
    i = iter(b)
    while True:
        print(next(i))
    
    #注意:此方法会while会无限循环,报错异常 StopIteration
    1. 异常捕捉
    b = {'a':1,'b':2,'c':3}
    i = iter(b)
    while True:
        try:        #注意此行
            print(next(i))
        except StopIteration:        #and this
            break    # and this
    1. for 循环机制
    for key in d:    #d即为d.__iter__() 迭代器放入原位置
        print(key)    #并且for循环具有异常捕捉的功能
    1. for 循环实现迭代器
    b = {'a':1,'b':2,'c':3}
    for i in b:
        print(i)
    1. 为什么要用迭代器
      • 优点
        1. 迭代器提供了一种不依赖于索引的取值方式,这样就可以遍历那些没有索引的可迭代对象了(字典、集合、文件)
        2. 迭代器与列表相比,迭代器是惰性计算的,更省内存(迭代器在内存中同一时刻只有一个值)
      • 缺点
        1. 无法获取迭代器的长度,使用不如列表索引取值灵活
        2. 一次性的,只能往后取值,不能倒着取值
    2. 查看可迭代对象与迭代器对象
    from collections import Iterable,Iterator
    
    s = 'hello'
    l = [1,2,3]
    t = (1,2,3)
    d = {'a':1}
    set1 = (1,2,3,4)
    f = open('a.txt')
    
    s.__iter__()
    l.__iter__()
    t.__iter__()
    d.__iter__()
    set1.__iter__()
    f.__iter__()
                                                        #Iterable 为可迭代的
    print(isinstance(s,Iterable))        #isinstance()  函数来判断一个对象是否是一个已知的类型,类似 type()。
    print(isinstance(l,Iterable))
    print(isinstance(t,Iterable))
    print(isinstance(d,Iterable))
    print(isinstance(set1,Iterable))
    print(isinstance(f,Iterable))
    1. 查看是否是迭代器
    print(isinstance(s,Iterator))        #Iterator 为迭代器
    print(isinstance(l,Iterator))
    print(isinstance(t,Iterator))
    print(isinstance(d,Iterator))
    print(isinstance(set1,Iterator))
    print(isinstance(f,Iterator))

    三. 生成器

    1. 定义:生成器就是一个函数,这个函数内包含有yield这个关键字,可以将函数变成具有序列性,返回多个值
    2. 生成器与return有何区别
      • return只能返回一次函数就彻底结束了,而yield能返回多次值
    3. yield到底干了什么事
      • yield把函数变成生成器(生成器其实就是迭代器)(yield将__next__和__iter__封装到函数内部)
      • 用return返回只能返回一次,而yield返回多次
      • 函数在暂停以及继续下一次运行时的状态是由yield保存
    def test():
        print('one')
        yield 1
        print('two')
        yield 2
        print('three')
        yield 3
    
    g = test()        #无输出,此时g为生成器,即把函数变成一个迭代器
    print(g)        #<generator object test at 0x00000000027E91A8>
    res = next(g)    #one        next触发生成器的执行
    print(res)        #1
    1. yield具体应用
    def countdown(n):
        print('start countdown')
        while n >0:
            yield n
            n -= 1
        print('done')
    
    g= countdown(5)
    
    print(next(g))        #start countdown    5
    print(next(g))        #4
    print(next(g))        #3
    print(next(g))        #2
    print(next(g))        #1
    print(next(g))        #done    #会报错
    
    #for循环写法
    for i in g:
        print(i)
    
    #while循环写法
    while True:
        try:
            print(next(g))
        except    StopIteration:
            break
    1. 生成器应用
    #惰性计算
    def func():
        n = 0
        while True:
            yield n
            n += 1
    
    f = func()
    print(next(f))
    1. tail命令的最基本实现
    import time
    def tail(file_path):
        with open(file_path,'r') as f:
            f.seek(0,2)                    #光标移到最后
            while True:
                    line = f.readline()            #读这一行
                    if not line:
                            time.sleep(0.5)
                            continue
                    else:
                            print line,        #print 输出光标不换行
    
    tail('/tmp/a.txt')
    1. tail命令通过生成器实现(python2)
    import time
    def tail(file_path):
        with open(file_path,'r') as f:
            f.seek(0,2)                    #光标移到最后
            while True:
                    line = f.readline()            #读这一行
                    if not line:
                            time.sleep(0.5)
                            print '======='
                            continue
                    else:
                            yield line
    
    g = tail('/tmp/a.txt')        #函数变成一个生成器
    
    for line in g:
            print line,
    1. grep命令通过生成器实现(python2)
    import time
    def tail(file_path):
        with open(file_path,'r') as f:
            f.seek(0,2)                    #光标移到最后
            while True:
                    line = f.readline()            #读这一行
                    if not line:
                            time.sleep(0.5)
                            continue
                    else:
                            yield line
    
    g = tail('/tmp/a.txt')
    
    for line in g:
            if 'error' in line:
                    print line,
    1. grep命令通过生成器实现且有水流概念
    import time
    def tail(file_path):
        with open(file_path,'r') as f:
            f.seek(0,2)                    #光标移到最后
            while True:
                    line = f.readline()            #读这一行
                    if not line:
                            time.sleep(0.5)
                            continue
                    else:
                            yield line
    
    def grep(pattern,lines):                #pattern 为grep所抓取的 lines为输入源
            for line in lines:
                    if pattern in line:
                            print line,
    
    g = tail('/tmp/a.txt')
    grep('error',g)
    1. tail、grep命令最终版
    import time
    #定义阶段:定义两个生成器函数
    def tail(file_path):
        with open(file_path,'r') as f:
            f.seek(0,2)                    #光标移到最后
            while True:
                    line = f.readline()            #读这一行
                    if not line:
                            time.sleep(0.5)
                            continue
                    else:
                            yield line
    
    def grep(pattern,lines):                #pattern 为grep所抓取的 lines为输入源
            for line in lines:
                    if pattern in line:
                            yield line
    
    #调用阶段:得到俩生成器对象
    g1 = tail('/tmp/a.txt')
    g2 = grep('error',g1)
    
    #使用阶段:next触发执行g2生成器函数
    for i in g2:
            print i,

    四. 协程函数

    1. 吃包子
    def eater(name):
        print('%s start to eat food '% name)
        food_list = []
        while True:
            food = yield food_list
            print('%s get %s, to start eat '% (name, food))
            food_list.append(food)
        print('Done')
    
    e = eater('钢蛋')
    
    print(next(e))
    print(e.send('包子'))
    print(e.send('韭菜包子'))    #send 等同于next 有返回值,但是会把后面的参数传给当前行的yield
    print(e.send('馅饼'))

    作业

    今日总结

    1. 待整理

    <wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">

  • 相关阅读:
    Revit二次开发示例:DisableCommand
    Revit二次开发示例:DesignOptions
    C# 非模式窗体show()和模式窗体showdialog()的区别
    Revit二次开发示例:DeleteObject
    被动永远做不好运维
    sudo开发常用命令总结
    ansible 配置了端口在host文件但是还要走22 ip:60001 ansible_ssh_port=60001
    ansible wc -l 对结果值取大小的操作
    mha切换脚本可用的
    mongoDB自动杀执行时间的连接
  • 原文地址:https://www.cnblogs.com/sama/p/7825403.html
Copyright © 2011-2022 走看看