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

一、迭代器

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}  # dic为可迭代对象
iter_dic= dic.__iter__()  # iter_dic为迭代器对象
print(iter_dic.__next__())
print(iter_dic.__next__())
print(iter_dic.__next__())

打印结果:x y z 会将键值打印出来


异常处理

如果循环取值,但是本身的值并没有那么多会出现什么情况呢?
当然会报错了,那么又有什么方法来控制呢
x=[1,2,3]
iter_x=x.__iter__()
while True:
    try:  # try 就相当于与一个监督作用,如果取出的值超出了x的范围,那么就会停止取值
        print(iter_x.__next__())
    except StopIteration:
        break
迭代器

 

4.可迭代对象与迭代器的比较

可迭代对象:

str,list,dict,tuple,set,file

获取可迭代对象方式:

无需获取,python内置str,list,dict,tuple,set,file都是可迭代对象

特点:

内置有__iter__方法的都叫可迭代的对象,执行该方法会拿到一个迭代器对象

 

迭代器对象:

文件对象本身就是迭代器对象

获取迭代器对象的方式:

执行可迭代对象的__iter__方法,拿到的返回值就是迭代器对象

特点:
内置有__next__方法,执行该方法会拿到迭代器对象中的一个值
内置有__iter__方法,执行该方法会拿到迭代器本身

 

5.迭代器优缺缺点

优点:

1.>可以不按照索引取值

因为它可以利用可迭代的对象执行__iter__方法直接得到的返回值

2.>节省内存

它可以将所有的值全部储存在一个空间,就是一个存储地址

 

缺点:

1.>取值麻烦

因为它取值只能一个一个取,取完前面才能取后面

2.>取值是一次性的,无法用len获取长度

 

6.for 循环原理分析

1.>for循环称之为迭代器循环,in后面跟的必须是可迭代对象

2.>for循环会执行in后面对象的__iter__方法,转成迭代器对象

3.>然后调用迭代器__next__方法,进行取值

4.>依次循环,直到取值完毕,检测到异常StopIteration,自动结束循环

 

二、生成器

1.生成器

生成器的本质就是迭代器

函数内包含yield关键字,在调用函数,

就不会执行函数体代码,拿到的返回值就是一个生成器

 

如果取值范围超过本身的数值范围会怎样呢?

 

既然会出现这种报错的情况,那么自然就有解决的方法

 

yield即可以返回一个值,也可以返回多个值,

并且多个值是以元组的形式返回,

如果yield后面没有数值,那么就会返回None

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

s = func()
print(s)
print(s.__next__())
print(s.__next__())
print(s.__next__())
print(s.__next__())

#  打印结果:
=====>first
1
=====>second
2
=====>third
(3, 4)
=====>forth
None
View Code

 

2.练习1:

自定义range功能

 需要取出range里的值
 平常是使用for循环来取值
for i in range(1,10):
    print(i)  # 打印结果:1~9的值
 这样就可以将其中的值全部取出,那么自定义生成器怎么取呢?
def my_range(start,end,step=1):
    while start < end:
        yield start
        start += step
for i in my_range(1,10):
    print(i)  # 打印结果:1~9的值
View Code

 3.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('jack')

1、必须初始化一次,让函数停在yield的位置
res0=dog1.__next__()
print(res0)

2、接下来的事,就是喂狗
send有两方面的功能
1、给yield传值
2、同__next__的功能
res1=dog1.send('泔水')
print(res1)
res2=dog1.send('骨头')
print(res2)
res3=dog1.send('shit')
print(res3)
yield的表达形式

4.yield与returnd的区别

yield

1.>会提供一种自定义生成的方式

2.>会将函数的运行状态暂时停住

3.>可以返回值,并且可以返回多个

4.>可以接受外部传入的值

return

1.>可以返回值,并且可以返回多个

2.>返回值后会将函数立即结束

5.生成器表达式

 

 生成器不会主动执行任何一行代码,必须通过__next__触发代码的运行
 

6.练习2:

def add(n,i):
    return n+i
def test():
    for i in range(4):
        yield i
g=test()

for n in [1,10]:
    g=(add(n,i) for i in g)
    # 第一次for循环g=(add(n,i) for i in test())

    # 第二次for循环g=(add(n,i) for i in (add(n,i) for i in test()))
print(n)
res=list(g)

"""
for i in (add(10,i) for i in test()):  会执行所有的生成器内部的代码
    add(n,i)
"""
View Code

 

三、常用内置函数方法

1.abs()  # 求绝对值
2.all() # 只要有一个为False就返回False
3.any() # 只要有一个位True就返回True
4.callabe() # 可调用的
5.chr() # 将数字转换成ascii码表对应的字符
6.ord() # 将字符按照ascii表转成对应的数字
7.dir() # 获取当前对象名称空间里面的名字
8.divmod() # 分页器
9.enumerate() # 枚举
10.eval() # 不支持逻辑代码,只支持一些简单的python代码
11.exec()
12.format #三种玩法 #{}占位 {index} 索引 {name} 指名道姓
13.isinstance # 后面统一改方法判断对象是否属于某个数据类型

 

四、面向过程编程

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 @ 2019-07-15 18:47  小青年て  阅读(127)  评论(0编辑  收藏  举报