函数篇:可迭代及迭代器对象、for循环的原理和本质、异常处理

2022.3.23学习笔记

  • 可迭代对象
  • 迭代器对象
  • for循环的内部原理
  • 异常处理
  • for循环的本质(代码模拟)
  • 迭代取值与索引取值的对比

一、可迭代对象

1、迭代的概念

迭代就是更新换代,每一次迭代都是基于上一次的结果,类似游戏版本的更新

特征:每一次的结果都不一样或者都有更新才叫做迭代

while True:
    print(123)  # 单纯的循环不叫迭代

n = 1
while True:
    print(n)
    n +=1  # 每次都不一样的,这样的循环才属于迭代
    
# 迭代取值
l1 = [11, 22, 33, 44, 55]
n = 0
while n < len(l1):
    print(len(n))
    n += 1

2、可迭代对象

内置有__iter__方法的都可成为可迭代对象,一般支持for循环的都是可迭代对象,如字符串、列表、字典、元组、集合、文件对象等

# 可迭代对象可以用.__iter__的方式进行调用
# __iter__读法:双下iter方法,不要读杠杠
s = 'jsdon'
s.__iter__

二、迭代器对象

1、概念

可迭代对象调用__iter__方法后生成的结果就是迭代器对象

2、特征

含有__iter__()方法和__next__()方法
s = 'jsdon'
res = s.__iter__()  # 将s转为迭代器对象
res.__next__()  # 使用next调用res这个迭代器对象,表示取第一个元素

3、迭代器对象的理解

作用:极大节省存储空间

类似哆啦a梦的口袋,不用的时候就是一个口袋,用的时候可以拿出很多东西

4、迭代器对象如何取值

调用__next__()方法即可
注意:如果数据取完了则会直接报错!!!
# for循环的底层依据就是迭代器对象

5、迭代器对象补充说明

(1)转化及调用的简易写法

__iter__() == iter()

__next__() == next()

(2)文件对象

文件对象本身就是迭代器对象,无须使用iter()调用

(3)多次调用iter()的结果

可迭代对象调用1次iter()会转化成迭代器对象,如果继续调用结果还是迭代器对象本身

res = s.__iter__()
res1 = s.__iter__().__iter__().__iter__()
res == res1  # 两个迭代器对象是一样的

(4)迭代取值的要求

s = 'jason'
print(s.__iter__().__next__())  # j
print(s.__iter__().__next__())  # j
print(s.__iter__().__next__())  # j
print(s.__iter__().__next__())  # j
print(s.__iter__().__next__())  # j

思考?为什么以上调用了5次结果一样呢?

这是因为s转化成迭代器对象之后需要一个变量名接收,不然再次调用还是从头开始的,因此要这样使用

s = 'jason'
res = s.__iter__()
print(res.__next__())  # j
print(res.__next__())  # a
print(res.__next__())  # s
print(res.__next__())  # o
print(res.__next__())  # n

三、for循环内部原理

先看for循环的结构:

for 变量名 in 可迭代对象:

​ 循环体代码

经过之前的学习,in后面相当于是将可迭代对象iter()一下变成迭代器对象,然后循环取里面的值,直到取完

l1 = [1, 2, 3, 4, 5, 6, 7]
res = l1.__iter__()
n = 0
while n < len(l1):
    print(res.__next__())
    n +=1  # 这里如果不进行人为计数,就会出现异常,也就是报错

所以什么是异常处理呢?

四、异常处理

1、什么是异常

代码运行出错之后就是异常,异常会导致程序立刻停止,因此我们再编写代码的时候需要极力避免(异常的外号叫:bug)

2、异常信息的组成部分(报错)

先看下面这个报错信息

1.Traceback (most recent call last):
2.  File "/Users/jiboyuan/PycharmProjects/day16/05 异常处理.py", line 3, in <module>
    name
3.NameError: name 'name' is not defined

序号1:line关键字所在的一行,用于提示哪一行报错,点击蓝色字体即可定位,如果报错信息很长,那么一般最后一个才是

序号2:NameError是错误的类型中的一种,还有很多其他类型

序号3:name 'name' is not defined是具体的报错原因,一般也是解决报错的方法

3、异常的分类

1.语法异常

最基础的语法结构,出现了会立即报错,pycharm中会出现红色波浪线

2.逻辑异常

不会直接报错,语法里有这个操作,但是乱用,比如:

name = 'jason'
name.append()  # 不会立马报错,但是字符串不可以使用列表内置方法,运行程序便会报错

如果逻辑异常,尽快修改即可

4、异常类型

举几个例子,如下

1.print(name)  # NameError 名字错误
2.l1 = [1, 2, 3]
print(l1[100])  # IndexError 索引错误
3.dict = {'name':'jason'}
print(dict['age'])  # KeyError 键错误
4.int('jason')  # ValueError 值错误
......

还有很多异常的类型,需要再改bug的时候多熟悉

五、异常处理实操

1、基本语法结构

try:
    可能会出错的代码
except 错误类型1 as e: # e指代错误提示信息
	针对1的处理措施
except 错误类型2 as e:
	针对2的处理措施
except 错误类型3 as e:
	针对3的处理措施
...

2、统一错误类型处理

由于有时候自己也不清楚是什么bug,使用下面的语法结构,可以对任意错误类型进行操作,也叫“万能异常”

try:
    可能会出错的代码
except Exception as e:
    统一的额处理措施

但是并不是以后都可以用这种方式,因为异常处理的准则就是被检测的代码越少越好,尽量少用

3、异常处理了解篇

(1)结合else使用

try检测的代码没有发生异常,正常运行完毕后会执行else的子代码

try:  # 检测代码有无异常
    可能会出错的代码
except Exception as e:  # 检测异常走except子代码  
    统一的处理措施
else:  # 检测无异常走else子代码
    可能会出错的代码没有出错 最后走else子代码

(2)结合finally使用

无论try检测的代码有无异常最后都会执行finally子代码

try:  # 检测代码有无异常
    可能会出错的代码
except Exception as e:  # 检测异常走except子代码  
    统一的处理措施
else:  # 检测无异常走else子代码
    可能会出错的代码没有出错 最后走else子代码
finally:  ####### 最后一步都会走finally
    无论上面有没有异常,最后都会走这一步

(3)assert断言

name = 'jaosn'
assert isinstance(name,str) 

(4)raise主动报错(需要掌握)

raise NameError('就是要报错,怎么了')
因为是主动报错,所以明确知道是什么错误

六、for循环的本质

了解了异常处理的一些知识,我们再回到for循环的原理上

l1 = [1, 2, 3, 4, 5, 6, 7]
res = l1.__iter__()
n = 0
while n < len(l1):
    print(res.__next__())
    n +=1  # 这里如果不进行人为计数,就会出现异常,也就是报错

刚才说了,这里如果不写n += 1,数据取完后就会报错,结合异常处理的知识我们可以这样做:

l1 = [1, 2, 3, 4, 5, 6, 7]
res = l1.__iter__()
while True:
    try:
        print(res.__next__())  # 检测这一行代码
    except StopIteration as e:  # 运行时了解到报错StopIteration
        break  # 报错直接退出循环

这样在我们知道报错的类型就可以加以相应的处理措施啦,是不是很神奇

七、迭代取值与索引取值的对比

1、索引取值

优势:可以反复取相同元素,没有固定方向

劣势:只能支持有序的容器类型,且兼容性没有迭代取值高

2、迭代取值

优势:兼容所有容器类型

劣势:永远是顺序取值,且无法重复获取,取完就结束

注意:迭代器里面的东西,取一个少一个,取完就没了

posted @ 2022-03-23 19:49  马氵寿  阅读(268)  评论(0)    收藏  举报