四.迭代器、生成器、面向过程编程

一.迭代器

1.1迭代的概念

# 迭代器即迭代的工具,那什么是迭代呢?#迭代是一个重复的过程,每次重复即一次迭代,并且每次迭代的结果都是下一次迭代的初始值
while True:  # 只是单纯地重复,因而不是迭代
    print('===>')

l = [1, 2, 3]
count = 0
while count < len(l):  # 迭代
    print(l[count])
    count += 1

# 基于索引的迭代取值
l = ['a', 'b', 'c']
i = 0

while i < len(l):
    print(l[i])
    i += 1

1.2为何要有迭代器?什么是可迭代对象?什么是迭代器对象?

#1、为何要有迭代器?
对于序列类型:字符串、列表、元组,我们可以使用索引的方式迭代取出其包含的元素。
但对于字典、集合、文件等类型是没有索引的,若还想取出其内部包含的元素,则必须找出一种不依赖于索引的迭代方式,这就是迭代器
#2、什么是可迭代对象? 可迭代对象指的是内置有__iter__方法的对象,即obj.__iter__,如下 'hello'.__iter__ (1,2,3).__iter__ [1,2,3].__iter__ {'a':1}.__iter__ {'a','b'}.__iter__ open('a.txt').__iter__ #3、什么是迭代器对象? 可迭代对象执行obj.__iter__()得到的结果就是迭代器对象 而迭代器对象指的是即内置有__iter__又内置有__next__方法的对象 文件类型是迭代器对象 open('a.txt').__iter__() open('a.txt').__next__() #4、注意: 迭代器对象一定是可迭代对象,而可迭代对象不一定是迭代器对象

 1.3迭代器对象的使用

dic={'a':1,'b':2,'c':3}
iter_dic=dic.__iter__() #得到迭代器对象,迭代器对象即有__iter__又有__next__,但是:迭代器.__iter__()得到的仍然是迭代器本身
iter_dic.__iter__() is iter_dic #True

print(iter_dic.__next__()) #等同于next(iter_dic)
print(iter_dic.__next__()) #等同于next(iter_dic)
print(iter_dic.__next__()) #等同于next(iter_dic)
# print(iter_dic.__next__()) #抛出异常StopIteration,或者说结束标志

#有了迭代器,我们就可以不依赖索引迭代取值了
iter_dic=dic.__iter__()
while 1:
    try:
        k=next(iter_dic)
        print(dic[k])
    except StopIteration:
        break
        
#这么写太丑陋了,需要我们自己捕捉异常,控制next,python这么牛逼,能不能帮我解决呢?能,请看for循环

1.4for循环

#基于for循环,我们可以完全不再依赖索引去取值了
dic={'a':1,'b':2,'c':3}
for k in dic:
    print(dic[k])

#for循环的工作原理
#1:执行in后对象的dic.__iter__()方法,得到一个迭代器对象iter_dic
#2: 执行next(iter_dic),将得到的值赋值给k,然后执行循环体代码
#3: 重复过程2,直到捕捉到异常StopIteration,结束循环

1.5迭代器的优缺点

#优点:
  - 提供一种统一的、不依赖于索引的迭代方式
  - 惰性计算,节省内存
#缺点:
  - 无法获取长度(只有在next完毕才知道到底有几个值)
  - 一次性的,只能往后走,不能往前退 

二.生成器

2.1什么是生成器?

生成器就是一种自定义的迭代器

2.2如何得到生成器?

但凡函数内出现yield关键字,再去调用户数不会立即执行函数体代码,会得到一个返回值,该返回值就是
生成器对象,即自定义的迭代器
#只要函数内部包含有yield关键字,那么函数名()的到的结果就是生成器,并且不会执行函数内部代码

def func():
    print('====>first')
    yield 1
    print('====>second')
    yield 2
    print('====>third')
    yield 3
    print('====>end')

g=func()
print(g) #<generator object func at 0x0000000002184360> 内存地址

res1=next(g)
print(res1)

res2=next(g)
print(res2)

res3=next(g)
print(res3)

# next(g)

# 总结yield:
# 1. 提供一种自定义迭代器的解决方案
# 2. yield & return
#    相同点: 都可以返回值,返回值没有类型限制\个数限制
#    不同点: return只能返回一次值,yield却可以让函数暂停在某一个位置,可以返回多次值

# 原理
# def my_range(start,stop,step=1):
#     while start < stop: # 5 < 5
#         yield start # 3
#         start+=step #start=5

# range(1,5,2) # 1 3
# for i in my_range(1,5000000000000000000000000000000000000000000,2): # 1 3
#     print(i)

三.面向过程编程

1 面向过程的编程思想
核心是'过程'二字,过程即解决问题的步骤,即先干什么,再干什么。。。。
基于面向过程编写程序就好比在设计一条流水线,是一种机械式的思维方式。

2、示范:

3、总结优缺点:
优点:复杂的问题流程化,进而简单化
缺点:修改一个阶段,其他阶段都有可能需要做出修改,牵一发而动全身,即扩展性极差
应用:用于扩展性要求低的场景
#1、步骤一:拿到用户输入的合法的信息:用户名、密码、余额、年龄
db_path='db.txt'

def get_uname():
    while True:
        uname=input('用户名>>:').strip()
        if not uname.isalpha():
            print('\033[45m用户名必须为英文字母...\033[0m')
            continue
        with open(r'%s' %db_path,'r',encoding='utf-8') as f:
            for line in f:
                uinfo=line.strip('\n').split(',')
                if uname == uinfo[0]:
                    print('\033[45m用户名已存在...\033[0m')
                    break
            else:
                return uname

def get_pwd():
    while True:
        pwd1=input('请输入密码>>: ').strip()
        pwd2=input('再次输入密码>>: ').strip()
        if pwd1 == pwd2:
            return pwd1
        else:
            print('\033[45m两次输入的密码不一致,请重新输入...\033[0m')

def get_bal():
    while True:
        bal=input('请输入余额: ').strip()
        if bal.isdigit():
            # bal=int(bal)
            return bal
        else:
            print('\033[45m钱必须是数字,傻叉...\033[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\n' %(uname,pwd,bal,age))

# 注册功能
def register():
    #步骤1:
    uname=get_uname() #拿到合法的用户名
    pwd=get_pwd() #拿到合法的密码
    bal=get_bal() #拿到合法的余额
    #步骤2:
    file_hanle(uname,pwd,bal) #写入文件

面向过程编程相关代码
面向过程编程相关代码

 

posted @ 2018-12-28 20:43  王苗鲁  阅读(67)  评论(0编辑  收藏  举报