zoukankan      html  css  js  c++  java
  • 迭代器、 生成器、 面向过程编程

    1  迭代器

    2  生成器

    3  面向过程编程


     6.10 迭代器

    1、什么是迭代:指的是一个重复的过程,每一次重复称为一次迭代,并且每一次重复的结果是下一次重复的初始值

    l=['a','b','c']
    count=0
    while count < len(l):   #只是单纯地重复,因而不是迭代
        print(l[count])
        count+=1

    2 为什么要有迭代器?

    对于序列类型:str,list,tuple,可以依赖索引来迭代取值,

    但是对于dict,set,文件,python必须为我们提供一种不依赖于索引的迭代取值的方式--》迭代器

    3、 可迭代的对象(下列都是):obj.__iter__

    name='egon'
    l=[1,2,3]
    t=(1,2,3)
    d={'name':'egon','age':18,'sex':'male'}
    s={'a','b','c'}
    f=open('a.txt','w',encoding='utf-8')
    
    name.__iter__
    l.__iter__
    t.__iter__
    d.__iter__
    s.__iter__
    f.__iter__

    4、 迭代器对象(文件是):obj.__iter__,obj.__next__

    f=open('a.txt','w',encoding='utf-8')
    f.__iter__
    f.__next__

    5、总结

    1 可迭代对象不一定是迭代器对象

    2 迭代器对象一定是可迭代的对象

    3 调用obj.__iter__()方法,得到的是迭代器对象,对于迭代器对象,执行__iter__得到的仍然是它本身)

    d={'name':'egon','age':18,'sex':'male'}
    d_iter=d.__iter__() #得到迭代器对象
    
    f=open('a.txt','w',encoding='utf-8')
    f_iter=f.__iter__().__iter__().__iter__().__iter__() #迭代器对象得到的仍然是它本身
    print(f_iter is f) #True
    
    
    #字典
    d={'name':'egon','age':18,'sex':'male'} #可迭代对象
    d_iter=d.__iter__() #迭代器对象
    print(d_iter.__next__())
    print(d_iter.__next__())
    print(d_iter.__next__())
    print(d_iter.__next__()) #迭代器d_iter没有值了,就会抛出异常StopIteration
     
    #文件
    f=open('a.txt','r',encoding='utf-8')
    print(f.__next__())
    print(f.__next__())
    print(f.__next__())
    print(f.__next__())
    f.close()
    
    #列表
    l=['a','b','c']
    l_iter=l.__iter__()
    print(l_iter.__next__())
    print(l_iter.__next__())
    print(l_iter.__next__())
    print(l_iter.__next__())
    
    #处理异常(可用for循环,for循环自带处理异常)
    d={'name':'egon','age':18,'sex':'male'}
    d_iter=iter(d) #d_iter=d.__iter__()
    while True:
        try:
            print(next(d_iter)) #print(d_iter.__next__())
        except StopIteration:  #捕获异常
            break
    
    print('=>>>')

    6、for循环详解:

       1、调用in后的obj_iter=obj.__iter__(),得到一个迭代器对象iter_dic

       2、k=obj_iter.__next__()

       3、重复过程2,直到捕捉到异常StopIteration,结束循环

    d={'name':'egon','age':18,'sex':'male'}
    for k in d:
        print(k)

    7、总结迭代器的优缺点:

    优点:

    1、提供一种统一的、不依赖于索引的取值方式,为for循环的实现提供了依据

    2、迭代器同一时间在内存中只有一个值——》更节省内存,

    缺点:

    1、只能往后取,并且是一次性的

    2、不能统计值的个数,即长度

    6.11 生成器

    6.11.1 生成器

    1、什么是生成器:只要在函数体内出现yield关键字,那么再执行函数就不会执行函数代码,会得到一个结果,该结果就是生成器

    def func():
        print('=====>1')
        yield 1
        print('=====>2')
        yield 2
        print('=====>3')
        yield 3

    2、生成器就是迭代器

    g=func()  #g是生成器
    res1=next(g)
    print(res1)
    
    res2=next(g)
    print(res2)
    
    res3=next(g)
    print(res3)

    3、yield的功能:

    1、yield为我们提供了一种自定义迭代器对象的方法

    2、yield与return的区别

    1)yield可以返回多次值

    2)函数暂停与再继续的状态是由yield帮我们保存的

    #自己编写rang()函数
    def my_range(start,stop,step=1):
        while start < stop:
            yield start  #start=1
            start+=step  #start=3
    
    g=my_range(1,5,2)
    print(g)
    #print(next(g))
    #print(next(g))
    for i in my_range(1,5,2):
        print(i)

    4、小练习::tail -f access.log | grep '404'

    import time
    def tail(filepath):
        with open(filepath,'rb') as f:
            f.seek(0,2)
            while True:
                line=f.readline()
                if line:
                    yield line
                else:
                    time.sleep(0.05)
    
    def grep(lines,pattern):
       for line in lines:
           line=line.decode('utf-8')
           if pattern in line:
               yield line
    
    lines=grep(tail('access.log'),'404')
    for line in lines:
        print(line)

    6.11.2 yield表达式形式的用法

    def eater(name):
        print('%s ready to eat' %name)
        food_list=[]
        while True:
            food=yield food_list  #food=yield='一盆骨头'
            food_list.append(food)
            print('%s start to eat %s' %(name,food))
    
    e=eater('alex')
    #首先初始化:
    print(e.send(None)) # next(e)
    #然后e.send:1 从暂停的位置将值传给yield  2、与next一样
    print(e.send('一桶泔水'))
    print(e.send('一盆骨头'))

    6.12 面向过程编程

    1、首先强调:面向过程编程绝对不是用函数编程这么简单,面向过程是一种编程思路、思想,而编程思路是不依赖于具体的语言或语法的。言外之意是即使我们不依赖于函数,也可以基于面向过程的思想编写程序

    2、定义

    面向过程的核心是过程二字,过程指的是解决问题的步骤,即先干什么再干什么

    基于面向过程设计程序就好比在设计一条流水线,是一种机械式的思维方式

    3、优点:复杂的问题流程化,进而简单化

    4、缺点:可扩展性差,修改流水线的任意一个阶段,都会牵一发而动全身

    5、应用:扩展性要求不高的场景,典型案例如linux内核,git,httpd

    6、举例

    流水线1:

    用户输入用户名、密码--->用户验证--->欢迎界面

    流水线2:

    用户输入sql--->sql解析--->执行功能

    grep -rl 'python' /etc

    # 第一步:拿到一个文件夹下所有的文件的绝对路径
    import os
    def init(func):
        def inner(*args,**kwargs):
            g=func(*args,**kwargs)
            next(g)
            return g
        return inner
    
    @init
    def search(target):  # r'D:videopython20期day4a'
        while True:
            filepath = yield
            g = os.walk(filepath)
            for pardir, _, files in g:
                for file in files:
                    abs_path = r'%s\%s' % (pardir, file)
                    #把abs_path传给下一个阶段
                    target.send(abs_path)
    
    # 第二步:打开文件拿到文件对象f
    @init
    def opener(target):
        while True:
            abs_path = yield
            with open(abs_path,'rb') as f:
                #把(abs_path,f)传给下一个阶段
                target.send((abs_path,f))
    
    #第三步:读取f的每一行内容
    @init
    def cat(target):
        while True:
            abs_path,f=yield
            for line in f:
                #把(abs_path,line)传给下一个阶段
                res=target.send((abs_path,line))
                #满足某种条件,break掉for循环
                if res:
                    break
    
    #第四步:判断'python' in line
    @init
    def grep(target,pattern):
        pattern = pattern.encode('utf-8')
        res=False
        while True:
            abs_path,line=yield res
            res=False
            if pattern in line:
                #把abs_path传给下一个阶段
                res=True
                target.send(abs_path)
    
    #第五步:打印文件路径
    @init
    def printer():
        while True:
            abs_path=yield
            print('<%s>' %abs_path)
    
    g=search(opener(cat(grep(printer(),'python')))) #'python' in b'xxxxx'
    g.send(r'D:videopython20期day4a')

    面向过程编程:核心是过程二字,过程指的就是解决问题的步骤,即先干什么后干什么。。。。

    基于该思路编写程序就好比设计一条流水线,是一种机械式的思维方式

    优点:复杂的问题流程化、进而简单化

    缺点:可扩展性差

  • 相关阅读:
    Git学习的网址
    (转)读懂diff
    如何让Beamer的logo放在右上角
    测试面试的一些分享
    python学习-使用制表符或者换行符来添加空白
    python学习-python变量的命名和使用
    python学习-运行.py时,python做了啥
    2020年,很特殊的1年
    python md5验签
    postman使用当前时间戳
  • 原文地址:https://www.cnblogs.com/snailgirl/p/8125032.html
Copyright © 2011-2022 走看看