zoukankan      html  css  js  c++  java
  • 30 Mar 18 迭代器 生成器 面向过程的编程

    30 Mar 18
    一、迭代器
    1、 迭代是一个重复的过程,并且每次重复都是基于上一次的结果而来 #仅仅循环,不是迭代
    2、 可迭代对象:在python中,但凡内置有__iter__方法的对象,都是可迭代的对象
       以下都是可迭代的对象
       str1='hello'
       list1=[1,2,3]
       tup1=(1,2,3)
       dic={'x':1}
       s1={'a','b','c'}
       f=open('a.txt','w',encoding='utf-8')
    3、 迭代器:迭代取值工具,可迭代的对象执行__iter__方法得到的返回值就是迭代器对象
    dic={'x':1,'y':2,'z':3}
    iter_dic=dic.__iter__()
    print(iter_dic.__next__())
    print(iter_dic.__next__())
    print(iter_dic.__next__())
    print(iter_dic.__next__())
    4、 可迭代的对象vs迭代器对象
    可迭代的对象:str,list,tuple,dict,set,file(文件本身就是迭代器)
    a、获取可迭代对象的方式:无须获取,python内置str,list,tuple,dict,set,file都是可迭代对象
    b、特点:
    内置有__iter__方法的都叫可迭代的对象,执行该方法会拿到一个迭代器对象
       
        迭代器对象:文件对象本身就是迭代器对象 #迭代器对象一定是可迭代对象
        a、获取迭代器对象的方式:
        执行可迭代对象的__iter__方法,拿到的返回值就是迭代器对象
        b、特点:
        内置有__next__方法,执行该方法会拿到迭代器对象中的一个值
    内置有__iter__方法,执行该方法会拿到迭代器本身
    iter_x=x.__iter__()
    iter_x.__next__()
    print(iter_x.__iter__().__iter__().__iter__().__iter__() is iter_x) #拿到的还是本身
     
    5、 迭代器的优缺点分析
    a.     迭代器提供了一种可不依赖于索引的取值方式(优点)
    #字典无序,没有办法通过索引取值,可通过迭代器取值
    l=open('a.txt','r',encoding='utf-8')
    iter_l=l.__iter__()
    while True:
        try:
            print(iter_l.__next__())
        except StopIteration:
            break
    b.     迭代器更加节省内存(优点)#迭代器本身是一个内存地址
    #range在python2中是一个列表,在python3中是一个迭代器
    c.      取值麻烦,只能一个一个取,只能往后取(缺点)
    d.     并且是一次性的,无法用len获取长度(缺点)
    6、 for循环原理分析
    a、for 循环称之为迭代器循环,in后跟的必须是可迭代的对象 #while 循环称为条件循环
    b、for循环会执行in后对象的__iter__方法,拿到迭代器对象
    c、然后调用迭代器对象的__next__方法,拿到一个返回值赋值给line,执行一次循环体
    d、周而复始,直到取值完毕,for循环会检测到异常自动结束循环
    for line in l: #iter_l=l.__iter__()
        print(line)
     
    for item in {'x':1,'y':2}:
    print(item)
     
    二、生成器:函数内包含有yield关键字,再调用函数,就不会执行函数体代码,拿到的返回值就是一个生成器对象
        def chicken():
        print('=====>first')
        yield 1
        print('=====>sencond')
        yield 2
        print('=====>third')
    yield 3
    obj=chicken()
    res=obj.__next__()
    print(res)
    res1=obj.__next__()
    print(res1)
    res2=obj.__next__()
    print(res2)
     
        1、iter_obj=obj.__iter__(),拿到迭代器
        2、触发iter_obj.__next__(),拿到该方法的返回值,赋值给item
        3、周而复始,直到函数内不在有yield,即取值完毕
        4、for会检测到StopIteration异常,结束循环
        for item in obj:
            print(item)
     
    总结yield:
    1、为我们提供了一种自定义迭代器的方式,可以在函数内用yield关键字,调用函数拿到的结果就是一个生成器,生成器就是迭代器
    2、yield可以像return一样用于返回值,区别是return只能返回一次值,而yield可返回多次。因为yield可以保存函数执行的状态
     
    def my_range():
        print('start........')
        n=0
        while True:
            yield n
            n+=1
     
    obj=my_range()
    print(obj)
     
    print(obj.__next__())
    print(obj.__next__())
    print(obj.__next__())
    print(obj.__next__())
     
    for i in my_range():
        print(i)
     
     
    def my_range(start,stop,step=1):
        n=start
        while n < stop:
            yield n #yield 4
            n+=step #5
     
     
    obj=my_range(3,7,2) #3,5,
    print(obj.__next__())
    print(obj.__next__())
    print(obj.__next__())
    print(obj.__next__())
    print(obj.__next__())
     
     
    for item in my_range(5,10,2):
    print(item)
     
    三、生成器之yield的表达式形式
    def eat(name):
        print('%s ready to eat' %name)
        food_list=[]
        while True:
            food=yield food_list # food='骨头'
            food_list.append(food) #food_list=['泔水','骨头']
            print('%s start to eat %s' %(name,food))
     
    dog1=eat('alex')
     
    1、必须初始化一次,让函数停在yield的位置
    res0=dog1.__next__()
    print(res0)
     
    2、接下来的事,就是喂狗
     
    send有两方面的功能
    a、给yield传值
    b、同__next__的功能
    res1=dog1.send('泔水')
    print(res1)
    res2=dog1.send('骨头')
    print(res2)
    res3=dog1.send('shit')
    print(res3)
     
    四、面向过程的编程思想
    1 面向过程的编程思想
        核心是'过程'二字,过程即解决问题的步骤,即先干什么,再干什么。。。。
        基于面向过程编写程序就好比在设计一条流水线,是一种机械式的思维方式。
     
    2、总结优缺点:
        优点:复杂的问题流程化,进而简单化
        缺点:修改一个阶段,其他阶段都有可能需要做出修改,牵一发而动全身,即扩展性极差
    应用:用于扩展性要求低的场景
     
     #1、步骤一:拿到用户输入的合法的信息:用户名、密码、余额、年龄
    db_path='db.txt'
     
    def get_uname():
        while True:
            uname=input('用户名>>:').strip()
            if not uname.isalpha():
                print('33[45m用户名必须为英文字母...33[0m')
                continue
            with open(r'%s' %db_path,'r',encoding='utf-8') as f:
                for line in f:
                    uinfo=line.strip('
    ').split(',')
                    if uname == uinfo[0]:
                        print('33[45m用户名已存在...33[0m')
                        break
                else:
                    return uname
     
    def get_pwd():
        while True:
            pwd1=input('请输入密码>>: ').strip()
            pwd2=input('再次输入密码>>: ').strip()
            if pwd1 == pwd2:
                return pwd1
            else:
                print('33[45m两次输入的密码不一致,请重新输入...33[0m')
     
    def get_bal():
        while True:
            bal=input('请输入余额: ').strip()
            if bal.isdigit():
                # bal=int(bal)
                return bal
            else:
                print('33[45m钱必须是数字,傻叉...33[0m')
     
    def get_age():
        pass
     
    #2、步骤二:写入文件
    def file_hanle(uname,pwd,bal,age):
        with open(r'%s' %db_path,'a',encoding='utf-8') as f:
            f.write('%s,%s,%s,%s
    ' %(uname,pwd,bal,age))
     
    # 注册功能
    def register():
        #步骤1:
        uname=get_uname() #拿到合法的用户名
        pwd=get_pwd() #拿到合法的密码
        bal=get_bal() #拿到合法的余额
        #步骤2:
        file_hanle(uname,pwd,bal) #写入文件
  • 相关阅读:
    vsftpd文件服务参数汇总和虚拟用户使用
    MHA实现mysql高可用复制集群
    mysqldump备份与基于bin-log实现完全恢复
    MySQL的日志相关内容
    MySQL(mariadb)主从复制模式与复制过滤
    MySQL(mariadb)多实例应用与多实例主从复制
    DNS的主从,转发与负载功能
    Spring 自动代理
    Jquery Validate 使用记坑
    动态代理
  • 原文地址:https://www.cnblogs.com/zhangyaqian/p/py20180330.html
Copyright © 2011-2022 走看看